处理用户互动

Glance 通过 Action 类简化了用户互动处理。Glance 的 Action 类定义了用户可以执行的操作,并且您可以指定为响应该操作而执行的操作。您可以使用 GlanceModifier.clickable 方法将 Action 应用于任何组件。

应用 widget 位于远程进程中,因此操作是在创建时定义的,执行发生在远程进程中。在原生 RemoteViews 中,此操作通过 PendingIntents 完成。

本页介绍了以下操作:

启动 activity

如需在用户互动时启动 activity,请通过 GlanceModifier.clickable(..) 修饰符将 actionStartActivity 函数提供给 Button 或其他可组合项。

actionStartActivity 中提供以下其中一项:

Glance 会将 Action 转换为 PendingIntent,并提供提供的目标和参数。在以下示例中,NavigationActivity 会在用户点击该按钮时启动:

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

启动服务

与启动 activity 类似,您可以使用任一 actionStartService 方法在用户互动时启动服务。

actionStartService 中提供以下其中一项:

@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 操作

您可以使用 lambda 函数作为对界面交互的回调。

例如,将 lambda 函数传递给 GlanceModifier.clickable 修饰符:

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

或者,在支持它的可组合项上将其传递给 onClick 形参:

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

运行 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
    }
}

在用户点击时,系统会调用所提供的 ActionCallbacksuspend onAction 方法,执行定义的逻辑(即请求刷新数据)。

如需在执行操作后更新 widget,请创建一个新实例并调用 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)
    }
}

为操作提供参数

如需为操作提供额外的信息,请使用 ActionParameters API 创建类型化键值对。例如,如需定义被点击的目的地,请使用以下代码:

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() }
    }
}

在下方,这些参数包含在用于启动 activity 的 intent 中,允许目标 activity 检索它。

    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
        // ...
    }
}