Obsługa interakcji użytkownika

Glance upraszcza obsługę interakcji użytkownika za pomocą klas Action. Klasy Action Glance definiują działania, które użytkownik może wykonać, i możesz określić operację wykonywaną w odpowiedzi na działanie. Możesz zastosować Action do dowolnego komponentu za pomocą metody GlanceModifier.clickable.

Widżety aplikacji działają w procesie zdalnym, więc działania są definiowane w momencie tworzenia, a wykonywanie odbywa się w procesie zdalnym. W natywnej usłudze RemoteViews odbywa się to za pomocą PendingIntents.

Na tej stronie opisano te działania:

Uruchamianie aktywności

Aby uruchomić aktywność w ramach interakcji użytkownika, podaj funkcję actionStartActivity do Button lub innego elementu kompozycyjnego za pomocą modyfikatora GlanceModifier.clickable.

Podaj jedną z tych informacji w actionStartActivity:

Glance przekształca działanie w PendingIntent z podanym celem i parametrami. W poniższym przykładzie NavigationActivity jest uruchamiany, gdy użytkownik kliknie przycisk:

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

Uruchamianie usługi

Podobnie jak w przypadku uruchamiania aktywności, uruchom usługę po interakcji użytkownika, używając jednej z metod actionStartService.

Podaj jedną z tych informacji w actionStartService:

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

Wysyłanie zdarzenia transmisji

Wyślij zdarzenie transmisji po interakcji użytkownika, korzystając z jednej z metod actionSendBroadcast:

Podaj jedną z tych informacji w actionSendBroadcast:

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

Wykonywanie działań niestandardowych

Zamiast uruchamiać konkretny element docelowy, Glance może użyć działania lambda lub actionRunCallback, aby wykonać działanie, takie jak aktualizacja interfejsu lub stanu po interakcji użytkownika.

Działania związane z uruchomieniem funkcji lambda

Funkcji lambda możesz używać jako wywołań zwrotnych do interakcji z interfejsem.

Na przykład przekaż funkcję lambda do modyfikatora GlanceModifier.clickable:

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

Możesz też przekazać go do parametru onClick w komponentach, które go obsługują:

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

Uruchom ActionCallback

Możesz też użyć metod actionRunCallback, aby wykonać działanie w ramach interakcji użytkownika. Aby to zrobić, podaj niestandardową implementację interfejsu 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
    }
}

Gdy użytkownik kliknie, wywoływana jest metoda suspend onAction podanego obiektu ActionCallback, która wykonuje zdefiniowaną logikę (np. żądanie odświeżenia danych).

Aby zaktualizować widżet po wykonaniu działania, utwórz nową instancję i wywołaj update(..). Więcej informacji znajdziesz w sekcji Zarządzanie stanem 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)
    }
}

Podawanie parametrów działań

Aby przekazać dodatkowe informacje do działania, użyj interfejsu API ActionParameters i utwórz parę klucz-wartość z określonym typem. Aby na przykład określić kliknięte miejsce docelowe:

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

Parametry są uwzględniane w intencji używanej do uruchomienia aktywności, co umożliwia docelowej aktywności ich pobranie.

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

Parametry są też przekazywane do ActionCallback. Użyj zdefiniowanego parametru Parameters.Key, aby pobrać wartość:

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