實踐 Android 7.1 快捷方式新模式
對于國內的一些 Android 用戶而言,可能對快捷方式的認識只是停留在讓國產流氓應用偷偷添加推廣鏈接,常常忽略方便好用的被動式快捷方式(通常在 Launcher 中添加小部件可以找到)。
到了 Android 7.1 , Google 重新重視快捷方式這一項功能,專門添加了一個新的模式。在已適配過特性的 Launcher 上(如 Pixel Launcher 、 Google Now Launcher 和 Nova Launcher ),用戶長按桌面上的 App 圖標即可顯示出開發者準備好的快捷方式。
對快捷方式的作用理解有很多,我們盡可能只把最需要或是最便捷的動作放上來,就如 Google 官方文檔 所說的:
-
在地圖應用中導航用戶到一個特定的地點
-
在通訊應用中發送信息給一位朋友
-
在媒體應用中播放下一集電視節目
-
在游戲中讀取上一個存檔點
這些動作除了可以在資源文件中預先編寫為靜態的快捷方式,然后在運行時進行修改;還可以在運行時通過 ShortcutManager API 推送、編輯、刪除動態的快捷方式。官方文檔所述一個應用最多推送五個快捷方式(包括靜態和動態的快捷方式),用戶可以將快捷方式固定到桌面,但應用無法刪除那些已固定的快捷方式,只能禁用它們。
靜態快捷方式?
靜態快捷方式,即是在 AndroidManifest 和資源文件預先聲明的一種快捷方式,除了受 Android 7.1 支持,還可以兼容低版本(當然了,都需要 Launcher 配合)。一般用作常用功能的固定入口(如新建信息、設置鬧鐘、顯示用戶一天的活動之類),也可以在后續代碼中通過 ShortcutManager 修改。
添加方法:
-
首先要定位到 AndroidManifest.xml 作為啟動入口的 Activity 。( Intent Filters 添加了 android.intent.action.MAIN 動作和 android.intent.category.LAUNCHER 分類的 Activity )。
-
參照以下的代碼,在 <meta-data> 元素中加入快捷方式的定義:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication"> <application ... > <activity android:name="Main"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" /> </activity> </application> </manifest>
-
在 /res/xml 創建一個新的資源文件 ( 例如 shortcuts.xml) 作為快捷方式的定義。
-
在這個新的資源文件中以 <shortcuts> 作為根 element ,其中包含若干個 <shortcut> 元素,記錄著各個快捷方式的圖標、標簽、長標題以及啟動 Intents:
<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <shortcut android:shortcutId="favorites" android:enabled="true" android:icon="@drawable/ic_shortcut_favourite" android:shortcutShortLabel="@string/label_favourites_shortcut" android:shortcutLongLabel="@string/label_favourites_shortcut_long"> <intent android:action="android.intent.action.VIEW" android:targetPackage="com.sspai.cuto.android" android:targetClass="com.sspai.cuto.android.ui.FavouritesActivity" /> <categories android:name="android.shortcut.conversation" /> </shortcut> <!-- 這里可以定義更多的快捷方式 --> </shortcuts>
-
到這里就完成了靜態快捷方式的定義了,效果如圖(此處用了第三方的 Launcher 顯示,會額外顯示一個 Icon options ,暫且不管):
動態快捷方式?
動態快捷方式,即是應用在運行時通過 ShortcutManager 進行動態添加的快捷方式,和以前所認識的“快捷方式”不同,它并不會直接丟到桌面而是像靜態快捷方式一樣顯示在一個菜單中,一般只用于上下文相關的特定操作(比如常用聯系人、訂閱的節目之類會在應用使用過程中不斷變化的數據)。這種快捷方式依賴于 Android 7.1 的新 API ,無法在低版本使用,這點需要注意。(期待 Google 推出相應的兼容庫)
ShortcutManager API 允許你進行下列操作:
-
推送:使用 setDynamicShortcuts(List) 來重新設置動態快捷方式的列表,或者使用 addDynamicShortcuts(List) 來添加到已存在的快捷方式列表。
-
更新:使用 updateShortcuts(List)
-
移除:使用 removeDynamicShortcuts(List) 來移除一些快捷方式,或者通過 removeAllDynamicShortcuts() 移除全部快捷方式。
下面的代碼片段就是創建一個動態快捷方式并添加到你的應用中:
ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "id1")
.setShortLabel("Web site")
.setLongLabel("Open the web site")
.setIcon(Icon.createWithResource(context, R.drawable.icon_website))
.setIntent(new Intent(Intent.ACTION_VIEW,
Uri.parse("https://www.mysite.example.com/")))
.build();
shortcutManager.setDynamicShortcuts(Arrays.asList(shortcut));
快捷方式的圖標設計
為了和 Android 系統、其他應用的風格一致,應當按照 Material Design Guideline 中的介紹設計,但我閱讀過程沒有找到相關的資料,可能是剛剛推出新特性尚未跟進設計文檔。
參考 Google 全家桶的應用后,在此提供個人總結的一些觀點:
-
圓形底板:我想這個不用多說吧。
-
無陰影:快捷方式菜單中圖標應和文本處于同一層面,而固定到桌面的快捷方式圖標會由 Launcher 自動添加上一層陰影。
-
色調一致:盡量統一使用產品的主色調(當圖標 Symbol 使用主色調時,背景使用 Grey 100 : #F5F5F5 )
在此我提供 Cuto 中的一個樣例和 PSD 模版供大家參考:
PSD 和 PNG : https://pan.baidu.com/s/1nuOlcpz
快捷方式的最佳實踐
-
只添加四個以內不同的快捷方式
盡管接口允許添加五個靜態或動態快捷方式,但還是應當只添加四個以內,這樣看上去會更加的整潔。
-
限制快捷方式的描述文本長度
快捷方式菜單的顯示空間很有限,短的描述應該控制在 10 個半角字符,而長描述應該控制在 25 個半角字符內。
-
動態快捷方式不會隨著手機數據備份還原
它并不會在備份還原的過程中保留,因此建議你在每次運行應用的時候通過 getDynamicShortcuts() 來檢查項目數量并在必要時重新添加快捷方式,例如以下代碼片段:
public class MainActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ShortcutManager shortcutManager = getSystemService(ShortcutManager.class); if (shortcutManager.getDynamicShortcuts().size() == 0) { // Application restored. Need to re-publish dynamic shortcuts. if (shortcutManager.getPinnedShortcuts().size() > 0) { // Pinned shortcuts have been restored. Use // updateShortcuts(List) to make sure they // contain up-to-date information. } } } // ... }
來自:http://blog.feng.moe/2016/11/03/android-new-shortcut-api/