google / glance-experimental-tools

Glance Experimental Tools aims to supplement Jetpack Glance with features that are commonly required by developers but not yet available.
https://developer.android.com/jetpack/androidx/releases/glance
Apache License 2.0
167 stars 12 forks source link

[appwidget-host] Improve compatibility with PagerApi #7

Closed ergofriend closed 1 year ago

ergofriend commented 1 year ago

Describe the bug

Render GlanceAppWidgetHostPreview on the page element of Pager, nothing appears on the page it was hidden. However, when I manually click on the element, it seems to reappear when the updateContent() specified for clickable is called.

To Reproduce

use GlanceAppWidgetHostPreview in HorizontalPager's page content

HorizontalPager(
            ...
        ) { page ->
            GlanceAppWidgetHostPreview()
}

https://user-images.githubusercontent.com/29725082/194844854-8f3ae730-1a81-44d9-a91b-ebe8e2ead9e0.mp4

Expected behavior

From the above event, I know that could display it by manually calling updateContent(). So I delayed updateContent() by 100 millis when it was mounted, and the element was always displayed before and after paging.

glance-experimental-tools/GlanceAppWidgetHostPreview.kt at b903edb88c898ca36c4a1b5099c2ebebd32ec6c9 · google/glance-experimental-tools

 if (hostState.isReady) {
   LaunchedEffect(hostState.value) {
+    delay(100)
     updateContent()
  }
}

https://user-images.githubusercontent.com/29725082/194844772-8bee4341-4775-4f3f-8b89-328f8c30bb4d.mp4

Environment:

compose_version = '1.2.1'
androidx.glance:glance-appwidget:1.0.0-alpha04
com.google.android.glance.tools:appwidget-configuration:0.2.2
com.google.accompanist:accompanist-pager:0.26.5-rc
github-actions[bot] commented 1 year ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.

b4rd commented 1 year ago

As a workaround I use runBlocking instead of LaunchedEffect.

Adding the following to AppWidgetHost also worked, but probably this isn't the right fix and the issue is rather related to how lazy composables and AndroidView interact.


update = { hostView ->
    if (hostView != state.value) {
        if (state.providerInfo != null) {
            hostView.setAppWidget(index, state.providerInfo)
            hostView.setPadding(0, 0, 0, 0)
        } else {
            // When no provider is provided, use a fake provider workaround to init the host
            hostView.setFakeAppWidget()
        }
    }
+    state.snapshot?.let {
+        hostView.updateAppWidget(it)
+    }
    state. Value = hostView
}