Как обрабатывать действия пользователей

Glance упрощает обработку действий пользователя с помощью классов Action. Классы GlanceAction определяют действия, которые может выполнить пользователь, а вы можете указать операцию, выполняемую в ответ на действие. Вы можете применить Action к любому компоненту с помощью метода GlanceModifier.clickable.

Виджеты приложений работают в удаленном процессе, поэтому действия определяются во время создания, а выполняются в удаленном процессе. В нативном приложении RemoteViews это делается с помощью PendingIntents.

На этой странице описаны следующие действия:

Как запустить дополнение

Чтобы запустить действие при взаимодействии пользователя, передайте функцию actionStartActivity в Button или другой компонуемый элемент с помощью модификатора GlanceModifier.clickable.

Укажите в поле actionStartActivity один из следующих вариантов:

  • Целевой класс действий
  • ComponentName
  • Намерение

Glance преобразует действие в событие PendingIntent с указанными целевым объектом и параметрами. В примере ниже NavigationActivity запускается, когда пользователь нажимает кнопку:

@Composable
fun MyContent() {
    // ..
    Button(
        text = "Go Home",
        onClick = actionStartActivity<MyActivity>()
    )
}

Запуск сервиса

Как и при запуске действия, запустите сервис при взаимодействии пользователя, используя один из методов actionStartService.

Укажите в поле actionStartService один из следующих вариантов:

  • Целевой класс действий
  • ComponentName
  • Намерение

@Composable
fun MyButton() {
    // ..
    Button(
        text = "Sync",
        onClick = actionStartService<SyncService>(
            isForegroundService = true // define how the service is launched
        )
    )
}

Как отправить трансляцию

Отправьте широковещательное событие при взаимодействии пользователя с помощью одного из методов actionSendBroadcast:

Укажите в поле actionSendBroadcast один из следующих вариантов:

@Composable
fun MyButton() {
    // ..
    Button(
        text = "Send",
        onClick = actionSendBroadcast<MyReceiver>()
    )
}

Выполнять специальные действия

Вместо запуска определенной цели Glance может использовать действие lambda или actionRunCallback для выполнения действия, например обновления интерфейса или состояния при взаимодействии с пользователем.

Как выполнять действия Lambda

Лямбда-функции можно использовать в качестве обратных вызовов для взаимодействия с интерфейсом.

Например, передайте лямбда-функцию модификатору GlanceModifier.clickable:

Text(
    text = "Submit",
    modifier = GlanceModifier.clickable {
        submitData()
    }
)

Или передайте его в параметр onClick в композициях, которые его поддерживают:

Button(
    text = "Submit",
    onClick = {
        submitData()
    }
)

Run ActionCallback

Также можно использовать методы actionRunCallback, чтобы выполнить действие при взаимодействии пользователя. Для этого реализуйте специальную версию ActionCallback:

@Composable
private fun MyContent() {
    // ..
    Image(
        provider = ImageProvider(R.drawable.ic_hourglass_animated),
        modifier = GlanceModifier.clickable(
            onClick = actionRunCallback<RefreshAction>()
        ),
        contentDescription = "Refresh"
    )
}

class RefreshAction : ActionCallback {
    override suspend fun onAction(
        context: Context,
        glanceId: GlanceId,
        parameters: ActionParameters
    ) {
        // TODO implement
    }
}

Когда пользователь нажимает на кнопку, вызывается метод suspend onAction предоставленного объекта ActionCallback, который выполняет заданную логику (например, запрашивает обновление данных).

Чтобы обновить виджет после выполнения действия, создайте новый экземпляр и вызовите метод update(..). Подробнее о том, как управлять состоянием GlanceAppWidget…

class RefreshAction : ActionCallback {
    override suspend fun onAction(
        context: Context,
        glanceId: GlanceId,
        parameters: ActionParameters
    ) {
        // do some work but offset long-term tasks (e.g a Worker)
        MyAppWidget().update(context, glanceId)
    }
}

Как передавать параметры в действия

Чтобы добавить к действию дополнительную информацию, используйте API ActionParameters для создания пары "ключ-значение". Например, чтобы определить целевую страницу, на которую переходит пользователь после нажатия, выполните следующие действия:

private val destinationKey = ActionParameters.Key<String>(
    NavigationActivity.KEY_DESTINATION
)

class MyAppWidget : GlanceAppWidget() {

    // ..

    @Composable
    private fun MyContent() {
        // ..
        Button(
            text = "Home",
            onClick = actionStartActivity<NavigationActivity>(
                actionParametersOf(destinationKey to "home")
            )
        )
        Button(
            text = "Work",
            onClick = actionStartActivity<NavigationActivity>(
                actionParametersOf(destinationKey to "work")
            )
        )
    }

    override suspend fun provideGlance(context: Context, id: GlanceId) {
        provideContent { MyContent() }
    }
}

Параметры включаются в намерение, используемое для запуска действия, и целевое действие может их извлечь.

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val destination = intent.extras?.getString(KEY_DESTINATION) ?: return
        // ...
    }
}

Параметры также передаются в ActionCallback. Используйте определенный элемент Parameters.Key, чтобы получить значение:

class RefreshAction : ActionCallback {

    private val destinationKey = ActionParameters.Key<String>(
        NavigationActivity.KEY_DESTINATION
    )

    override suspend fun onAction(
        context: Context,
        glanceId: GlanceId,
        parameters: ActionParameters
    ) {
        val destination: String = parameters[destinationKey] ?: return
        // ...
    }
}