转载自http://blog.youkuaiyun.com/qibin0506/article/details/52878690
就在前几天的一个晚上, Google召开了它的秋季发布会, 毫无悬念的宣布了它的最新手机品牌Pixel, 与此同时我的nexus设备也从亲儿子降级成为干儿子. 不过还好Google并没有对这一干一亲区别对待, 这不, 今天就推送了android7.1.1的更新, 随之而来的又是一大波新特性(又有我们开发者忙的了…), 这其中一个叫作Shortcuts
的功能真的是太赞了, 利用这个功能以后我们就再也不用一页一页的进入我们想要的页面了, 在桌面长按图标就可以快捷进入(唉, 国产APP这个功能估计要等好久好久…), 而且, 这个快捷方式是我们开发者去自定义了! 所以, 就在API发布的当天晚上, 我从文档中了解了一下这个新特性, 然后就有了这篇文章.
Shortcuts初体验
好了, 在我们开始撸码之前, 还是来看看这个新特性有多赞, 新系统中好多google家的APP都集成了这项功能, 所以, 我们先挑个APP来体验一下.
这个功能还是很实用的, 有了它, 我们就可以直接打开短信应用给某人发短信啦~~ 下面我们就开始学习一下这个新的Shortcuts在开发中如何使用!
使用Static Shortcuts
什么是Static Shortcuts? 我的理解就是利用xml写死的配置, 想想BroadcastReceiver
可以静态注册也可以利用Java代码动态注册, 这里也是一样的.
那静态注册该如何做呢? 首先, 我们需要在res/xml
目录下创建一个新的xml文件, 这里我们命名为shortcuts.xml
.
<code class="language-xml hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">shortcuts</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res/android"</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">shortcut </span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:shortcutId</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"settings"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:enabled</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"true"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:icon</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@drawable/icon"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:shortcutShortLabel</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@string/settings_short_name"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:shortcutLongLabel</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@string/settings_long_name"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:shortcutDisabledMessage</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@string/settings_disable_msg"</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">intent </span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:action</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"android.intent.action.VIEW"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:targetPackage</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"org.loader.shotcutsstatic"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:targetClass</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"org.loader.shotcutsstatic.SettingsActivity"</span> /></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">categories</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"android.shortcut.conversation"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">shortcut</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">shortcuts</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>
首先一个shortcuts
标签, 然后是一个shortcut
, 到这里我们大概可以猜测到这里可以注册多个shortcut
, shortcut
标签有很多属性, 我们来一个个的了解下.
- shortcutId, 不用多说, 这肯定是一个唯一的id
- enabled, 表示这个shortcut是否可用
- shortcutShortLabel, 这里是配置的短名称, 下面还会有长名称, 如果长名称显示不下, 就显示短名称
- shortcutLongLabel, 这里是配置的长名称, launcher会优先选择长名称显示
- shortcutDisabledMessage, 这个配置是在我们选择一个不可用的shortcut时给用户的一个提示
在shortcut
标签下还有两个我们熟悉的标签.
- intent, 这里表示我们点击shortcut时要干嘛, targetPackage是指定一个目标应用的包名, targetClass是我们要跳转的目标类, 这里要注意的是
android:action
一定要配置, 否则会崩溃- categories, 这个东西目前位置官方只给提供了
android.shortcut.conversation
ok, 上面的几行代码, 我们一个static shortcuts
就完成了, 那如何使用呢? 是在manifest中配置activity的地方使用, 而且这个activity是有要求的.
能配置shortcuts
的activity必须要有action
是Android.intent.action.MAIN
和category
是android.intent.category.LAUNCHER
!
为什么要有这个要求, 自己去体会…
最终, 我们来看看这个配置:
<code class="language-xml hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">application </span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:allowBackup</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"true"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:icon</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@mipmap/ic_launcher"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:label</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@string/app_name"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:supportsRtl</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"true"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:theme</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@style/AppTheme"</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">activity</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">".MainActivity"</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">intent-filter</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">action</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"android.intent.action.MAIN"</span> /></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">category</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"android.intent.category.LAUNCHER"</span> /></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">intent-filter</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">meta-data </span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"android.app.shortcuts"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:resource</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@xml/shortcuts"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">activity</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">activity</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">".SettingsActivity"</span> /></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">application</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li></ul>
来看看最终实现的效果:
ok, 到这里, 静态配置shortcuts
我们就学习完了, 是不是很简单? 那这个静态配置是用在什么地方呢? 我想了想, 这里适用的场景一般是一些固定不变的功能, 例如你APP的设置界面, 如果是一些动态的数据, 那静态配置就不适合了, 就需要我们接下来要介绍到了动态配置了.
使用Dynamic Shortcuts
在看完Static Shortcuts后, 我们不相信Google仅仅给我们开发者开放了局限性如此大的使用方式, 肯定还会存在灵活性更大的API, 是的, 这就是我们马上要讲的Dynamic Shortcuts
, 我把它称为动态配置.
说起动态配置, 那肯定是用java代码实现了, 那如何实现呢?
首先第一步, 我们需要利用一下代码拿到ShortcutManager
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">getSystemService(ShortcutManager.class)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
拿到ShortcutManager
后, 我们可以调用setDynamicShortcuts(List<ShortcutInfo>)
方法去设置Shortcut, 那这个List如何得到呢? 我们来看看完整点的代码,
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setupShortcuts</span>() { mShortcutManager = getSystemService(ShortcutManager.class); List<ShortcutInfo> infos = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<>(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < mShortcutManager.getMaxShortcutCountPerActivity(); i++) { Intent intent = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Intent(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, MessageActivity.class); intent.setAction(Intent.ACTION_VIEW); intent.putExtra(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msg"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"我和"</span> + mAdapter.getItem(i) + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"的对话"</span>); ShortcutInfo info = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ShortcutInfo.Builder(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"id"</span> + i) .setShortLabel(mAdapter.getItem(i)) .setLongLabel(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"联系人:"</span> + mAdapter.getItem(i)) .setIcon(Icon.createWithResource(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, R.drawable.icon)) .setIntent(intent) .build(); infos.add(info); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// manager.addDynamicShortcuts(Arrays.asList(info));</span> } mShortcutManager.setDynamicShortcuts(infos); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul>
这段代码的背景是我们模拟了一个联系人列表功能, 在launcher中我们长按图标会出现一定数量的联系人快捷方式, 点击某个快捷方式会直接跳转该联系人相关的页面. 好, 介绍完背景, 我们来看代码, 首先我们通过getSystemService(ShortcutManager.class)
来拿到ShortcutManager
, 接下来一个for循环, 注意这个for循环的次数, 因为我们要添加的Shortcut
不能是无限个, 所以这里我们用getMaxShortcutCountPerActivity
来获取到最大个数. 然后在for循环里, 我们首先构造一个intent, 注意, 这里和Static Shortcut
一样, 必须要提供一个Action
. 然后我们用ShortcutInfo.Builder
来构造一个ShortcutInfo
并且放到List中, 最终我们调用mShortcutManager.setDynamicShortcuts(infos)
来设置Shortcuts.
好了, 代码其实很简单, 我们来看看效果.
是不是很666?
动态更新 Shortcuts
上面的代码我们虽然说是Dynamic, 但仅仅是使用java代码实现的罢了, 真正的Dynamic我们接下来才去讲解, 在讲解Dynamic之前, 我们先来介绍一个名词-Pinning Shortcuts
, 这是个啥玩意呢? 其实对于Shortcut
, Android是允许我们直接放到桌面的, 这样就更加方便了用户的操作, google把他称作为Pinning Shortcuts
, 具体啥样, 我们来张图就明白了.
对于这个Pinning Shortcuts
, google的文档说, 我们开发者是没有权利去删除的, 能删除它的只有用户. 那我该项功能删除了咋办? 这东西还在桌面上, 是不是APP要崩? 当然Google考虑到了这点, 它允许我们去disable
这个shortcut
. 具体还是来看代码, 这里我们长按item来模拟一下删除.
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">removeItem</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> index) { List<ShortcutInfo> infos = mShortcutManager.getPinnedShortcuts(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (ShortcutInfo info : infos) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (info.getId().equals(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"id"</span> + index)) { mShortcutManager.disableShortcuts(Arrays.asList(info.getId()), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"暂无该联系人"</span>); } } mShortcutManager.removeDynamicShortcuts(Arrays.asList(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"id"</span> + index)); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>
首先我们先调用mShortcutManager.getPinnedShortcuts()
来获取到所有的Pinning Shortcuts
, 然后去遍历它, 找到我们删除的那个, 然后通过APIdisableShortcuts(List<Ids>)
来disable
掉该项, 最后我们还要用过removeDynamicShortcuts(List<Ids>)
来从shortcuts
中移除. 来看看效果.
通过效果中, 我们可以看到, 我们disableShortcuts
的那个Pinning Shortcut
已经变灰了, 而且在点击的时候会提醒暂无该联系人
, 这个提醒正是disableShortcuts
的第二个参数.
现在, 删除和禁用我们已经了解了, 那更新呢? 假如我修改了某个联系人的名字, shortcut
是不是也应该相应的修改呢? 是的, 这里还是需要我们通过代码来实现.
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">updItem</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> index) { Intent intent = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Intent(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, MessageActivity.class); intent.setAction(Intent.ACTION_VIEW); intent.putExtra(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msg"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"我和"</span> + mAdapter.getItem(index) + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"的对话"</span>); ShortcutInfo info = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ShortcutInfo.Builder(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"id"</span> + index) .setShortLabel(mAdapter.getItem(index)) .setLongLabel(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"联系人:"</span> + mAdapter.getItem(index)) .setIcon(Icon.createWithResource(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, R.drawable.icon)) .setIntent(intent) .build(); mShortcutManager.updateShortcuts(Arrays.asList(info)); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>
构建intent我们就不说了, 接下来我们又使用ShortcutInfo.Builder
来构建了一个新的ShortcutInfo
, 最后我们是用过updateShortcuts(List<ShortcutInfo>)
来实现更新shortcut
的, 很简单, 来看看效果.
ok, 现在, Android7.1的Shortcuts
功能我们就差不多介绍完了, 文章中的实例代码大家可以在https://github.com/qibin0506/Android7_Shortcuts_Demo上下载到, 官网的文档大家也可以多看看, 这里给出地址: https://developer.android.com/preview/shortcuts.html