- PVSM.RU - https://www.pvsm.ru -
Привет! Предлагаю вашему вниманию свободный перевод статьи «Exploring Android Nougat 7.1 App Shortcuts [1]» от Andrei Catinean [2].
Google выпустил Android Nougat с версией 7.1 (API 25). Появились некоторые интересные функции под капотом. Одна из этих дополнительных функций — app shortcuts. Эта статья расскажет, что они собой представляют, как они работают, и как вы можете их реализовать.
Ярлыки приложений — это средство изображения общих действий или задач вашего приложения на главном экране пользователя. Ваши пользователи могут раскрыть ярлыки при долгом нажатии запуска программы. С технической точки зрения, ярлыки приложений — это простой и быстрый способ использования intents.
Предоставляя свои общие задачи, вы упростите пользователям возможность быстро вернуться к определенным частям вашего приложения без дополнительной навигации и без лишних переходов по активностям.
Добавление ярлыков в ваше приложение довольно просто. Начнем с создания простого статического ярлыка.
В этом примере предполагается, что у вас уже создан проект в Android Studio.
Перейдите в AndroidManifest.xml и добавьте следующий тег метаданных в свою основную активность:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.catinean.appshortcutsdemo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>
</application>
</manifest>
В теге meta-data ключ android:resource соответствует ресурсу, определенному в файле res / xml / shortcuts.xml. Здесь вам нужно определить все ваши статические ярлыки. Давайте добавим тот, который откроет определенную активность из вашего приложения.
В приведенном ниже примере я создал фиктивный StaticShortcutActivity:
<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:enabled="true"
android:icon="@drawable/ic_static_shortcut"
android:shortcutDisabledMessage="@string/static_shortcut_disabled_message"
android:shortcutId="static"
android:shortcutLongLabel="@string/static_shortcut_long_label"
android:shortcutShortLabel="@string/static_shortcut_short_label">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.catinean.appshortcutsdemo.StaticShortcutActivity"
android:targetPackage="com.catinean.appshortcutsdemo" />
</shortcut>
</shortcuts>
Вы можете видеть, что корневой тег этого файла <shortcuts>
, который может содержать несколько блоков <shortcut>
. Каждый из них, как вы могли догадаться, представляет собой статический ярлык. Здесь для одного ярлыка можно задать следующие свойства:
<shortcuts>
.Вот как этот ярлык будет отображаться пользователю вашего приложения:
Просто и понятно, но если вы это реализуете, то вы можете заметить, что при нажатии на кнопку "назад" пользователь возвращается на домашний экран.
Как насчет того, чтобы вместо этого перейти в приложение? Для этого мы можем добавить несколько intent-тэгов в ярлыках, которые мы ранее создали:
<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
...>
<intent
android:action="android.intent.action.MAIN"
android:targetClass="com.catinean.appshortcutsdemo.MainActivity"
android:targetPackage="com.catinean.appshortcutsdemo" />
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.catinean.appshortcutsdemo.StaticShortcutActivity"
android:targetPackage="com.catinean.appshortcutsdemo" />
</shortcut>
</shortcuts>
Обратите внимание, как мы добавили дополнительный <intent>
до того, что у нас было, указав на MainActivity. Это создаст back stack намерений, последний из которых будет открыт ярлыком. В нашем случае back stack выглядит как MainActivity -> Static ShortcutActivity, поэтому при нажатии назад пользователь переходит в MainActivity:
Добавление статических ярлыков довольно просто. Давайте перейдем к динамическим.
Как следует из их названия, динамические ярлыки могут быть изменены во время выполнения без необходимости повторного открытия вашего приложения. Как вы могли догадаться, они не определяются через статический ресурс (shortcuts.xml), как статические, но создаются в коде.
Давайте добавим наш первый динамический ярлык!
Для этого вам нужно будет использовать ShortcutManager [3] и ShortcutInfo.Builder [4]. Я буду создавать первый динамический ярлык в моей MainActivity.#OnCreate ():
@Override
protected void onCreate(Bundle savedInstanceState) {
...
ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
ShortcutInfo webShortcut = new ShortcutInfo.Builder(this, "shortcut_web")
.setShortLabel("novoda.com")
.setLongLabel("Open novoda.com web site")
.setIcon(Icon.createWithResource(this, R.drawable.ic_dynamic_shortcut))
.setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse("https://novoda.com")))
.build();
shortcutManager.setDynamicShortcuts(Collections.singletonList(webShortcut));
}
В приведенном выше примере мы используем shortcutManager и создаем ShortcutInfo. Используя ShortcutInfo.Builder, мы можем установить различные свойства для ярлыка, который мы хотим создать. Все методы, которые мы используем выше, соответствуют тем же, что и для статического ярлыка. Однако одно свойство, которое является немного неясным, является идентификатором ярлыка, который определен в конструкторе StaticInfo.Builder как второй параметр — shortcut_web. В приведенном выше примере я определил намерение, которое откроет мой сайт. Наконец, я установил динамический ярлык в ShortcutManager. Посмотрим теперь, как выглядят наши ярлыки:
Круто! Теперь у нас есть 2 быстрых ярлыка в нашем приложении — один статический и одий динамический.
Давайте добавим еще один, который укажет на активность внутри приложения и посмотрим, как мы можем создать для него back stack:
@Override
protected void onCreate(Bundle savedInstanceState) {
...
ShortcutInfo dynamicShortcut = new ShortcutInfo.Builder(this, "shortcut_dynamic")
.setShortLabel("Dynamic")
.setLongLabel("Open dynamic shortcut")
.setIcon(Icon.createWithResource(this, R.drawable.ic_dynamic_shortcut_2))
.setIntents(
new Intent[]{
new Intent(Intent.ACTION_MAIN, Uri.EMPTY, this, MainActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK),
new Intent(DynamicShortcutActivity.ACTION)
})
.build();
shortcutManager.setDynamicShortcuts(Arrays.asList(webShortcut, dynamicShortcut));
}
Вы можете видеть, что теперь мы создаем setIntents () в builder'е, чтобы построить back stack:
Первое намерение соответствует MainActivity. Мы определяем флаг FLAG_ACTIVITY_CLEAR_TASK [5], чтобы очистить все существующие задачи, связанные с приложением, и сделать MainActivity текущим корневым действием
<activity
android:name=".DynamicShortcutActivity"
android:label="Dynamic shortcut activity">
<intent-filter>
<action android:name="com.catinean.appshortcutsdemo.OPEN_DYNAMIC_SHORTCUT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Объявив массив намерений в этом порядке, то гарантируем, что когда пользователь вернется после открытия DynamicShortcutActivity, то MainActivity будет открыт.
Как это выглядит:
Теперь, когда у нас есть 1 статический ярлык и 2 динамических, как мы можем задать для них порядок? Если мы более подробно рассмотрим методы ShortcutInfo.Builder, в частности: setRank (int). Установив настраиваемый ранг в динамический ярлык, мы можем контролировать порядок, в котором они появляются: чем выше ранг, тем выше ярлык.
В качестве примера, скажем, мы хотим, чтобы ярлык №2 (novoda.com) находился на вершине. Мы можем динамически изменять ряды уже добавленных динамических ярлыков. Давайте сделаем это, нажав кнопку в MainActivity:
findViewById(R.id.main_rank_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ShortcutInfo webShortcut = new ShortcutInfo.Builder(MainActivity.this, "shortcut_web")
.setRank(1)
.build();
ShortcutInfo dynamicShortcut = new ShortcutInfo.Builder(MainActivity.this, "shortcut_dynamic")
.setRank(0)
.build();
shortcutManager.updateShortcuts(Arrays.asList(webShortcut, dynamicShortcut));
}
});
В слушателе кнопки мы создаем новый ShortcutInfo для каждого ярлыка, которые мы ранее добавляли с теми же идентификаторами, но теперь мы устанавливаем более высокий ранг в shortcut_web, а нижний — для shortcut_dynamic. Наконец, мы используем метод updateShortcuts (List <ShortcutInfo>
) для обновления ярлыков:
Вы можете видеть из приведенной выше гифки, что статический ярлык находится внизу списка. Важное замечание: вы не можете изменить ранг статического ярлыка. Они будут показаны в том порядке, в котором они определены в файле shortcuts.xml. Поскольку у нас есть только один статический ярлык, он имеет ранг по умолчанию 0, который нельзя изменить.
Если мы более подробно рассмотрим метод setShortLabel (CharSequence), мы увидим, что он принимает CharSequence в качестве параметра. Что это значит? Ну, это означает, что мы можем немного поиграть с ним :-)
Предположим, мы хотим изменить цвет на красный, нажав на созданную выше кнопку. Мы можем создать SpannableStringBuilder и установить для него ForegroundColorSpan требуемый цвет, а затем передать spannableStringBuilder как shortLabel (поскольку SpannableStringBuilder реализует CharSequence):
findViewById(R.id.main_rank_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ForegroundColorSpan colorSpan = new ForegroundColorSpan(getResources().getColor(android.R.color.holo_red_dark, getTheme()));
String label = "novoda.com";
SpannableStringBuilder colouredLabel = new SpannableStringBuilder(label);
colouredLabel.setSpan(colorSpan, 0, label.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
ShortcutInfo webShortcut = new ShortcutInfo.Builder(MainActivity.this, "shortcut_web")
.setShortLabel(colouredLabel)
.setRank(1)
.build();
...
}
});
Исходники [6] приложения из статьи
Автор: Артём Клименко
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/android-development/262472
Ссылки в тексте:
[1] Exploring Android Nougat 7.1 App Shortcuts: https://www.novoda.com/blog/exploring-android-nougat-7-1-app-shortcuts/
[2] Andrei Catinean: https://www.novoda.com/blog/author/andrei-catinean/
[3] ShortcutManager: https://developer.android.com/reference/android/content/pm/ShortcutManager.html
[4] ShortcutInfo.Builder: https://developer.android.com/reference/android/content/pm/ShortcutInfo.Builder.html
[5] FLAG_ACTIVITY_CLEAR_TASK: https://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TASK
[6] Исходники: https://github.com/Electryc/AppShortcutsDemo
[7] Источник: https://habrahabr.ru/post/335480/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.