處理使用者互動

Glance 可透過 Action 類別簡化使用者互動作業。Glance 的 Action 類別定義了使用者能採取的動作,您也可以指定回應動作所執行的作業。使用 GlanceModifier.clickable 方法,即可將 Action 套用至任何元件。

應用程式小工具會在遠端程序中運作,因此動作會在建立時間定義,並在遠端程序中執行。在原生 RemoteViews 中,這項作業是透過 PendingIntents 完成。

本頁說明下列動作:

啟動活動

如要在使用者互動時啟動活動,請透過 GlanceModifier.clickable(..) 修飾符將 actionStartActivity 函式提供給 Button 或其他可組合項。

actionStartActivity 中提供下列其中一項資訊:

Glance 將動作轉換成含有所提供目標和參數的 PendingIntent。在以下範例中,系統會在使用者點選按鈕時啟動 NavigationActivity

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

啟動服務

與啟動活動類似,使用其中一種 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 執行動作,例如:更新使用者互動的 UI 或狀態。

執行 lambda 動作

您可以使用 lambda 函式做為 UI 互動的回呼。

例如,將 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 方法,執行定義的邏輯 (即要求重新整理資料)。

如要在執行操作後更新小工具,請建立新的執行個體並呼叫 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() }
    }
}

簡單來說,這些參數會包含在啟動活動的意圖中,讓目標活動能夠擷取。

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