Status Update
Comments
ap...@google.com <ap...@google.com> #2
Which API level are you seeing the issue here with?
ap...@google.com <ap...@google.com> #3
My hunch is that this is related to DialogFragment
or ComponentDialog
adds a new Window
that the contained ComposeView
is not aware of.
ap...@google.com <ap...@google.com> #4
I've only tested this on API level 33 and 26 so far, and out of these two I'm seeing this only on 33
ap...@google.com <ap...@google.com> #5
Hello,
We're also experiencing this issue starting from compose 1.4.0-alpha03 and API level >= 30.
Attaching min repro project. Similar issue was filed in Aug 25, 2021 here
ap...@google.com <ap...@google.com> #6
Experiencing the same issue. Slowly migrating the project to compose and i still need the some compose views to be inside a DialogFragment.
ap...@google.com <ap...@google.com> #7
Faced the same and like #3 mentioned, compose switched to use a DialogWindowProvider
to figure out its window.
To workaround it in the meantime I copied ComposeView and made it report my dialog window. Not easy, but you cant get past creating a subclass.
internal abstract class ComposeBottomSheetFragment : BottomSheetDialogFragment() { // Can be simple DialogFragment
@Composable protected abstract fun Content()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return ComposeDialogView(requireContext()).also {
it.consumeWindowInsets = false
it.layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT)
it.setContent {
OurTheme { Content() }
}
}
}
// Copy of ComposeView that is able to supply the dialog window to compose.
// I used inner class but you can also pass a lambda to the view and lazily request the window
inner class ComposeDialogView(context: Context) : AbstractComposeView(context, null, 0), DialogWindowProvider {
// The important bit
override val window get() = requireDialog().window!!
private val content = mutableStateOf<(@Composable () -> Unit)?>(null)
override var shouldCreateCompositionOnAttachedToWindow: Boolean = false
private set
@Composable
override fun Content() {
content.value?.invoke()
}
override fun getAccessibilityClassName(): CharSequence = ComposeView::class.java.name
/**
* Set the Jetpack Compose UI content for this view.
* Initial composition will occur when the view becomes attached to a window or when
* [createComposition] is called, whichever comes first.
*/
fun setContent(content: @Composable () -> Unit) {
shouldCreateCompositionOnAttachedToWindow = true
this.content.value = content
if (isAttachedToWindow) createComposition()
}
}
private var ComposeDialogView.consumeWindowInsets: Boolean
get() = getTag(androidx.compose.ui.R.id.consume_window_insets_tag) as? Boolean ?: true
set(value) {
setTag(androidx.compose.ui.R.id.consume_window_insets_tag, value)
}
}
ap...@google.com <ap...@google.com> #8
That workaround should work, due to this line:
Only seeing this issue on API 30 and above also makes sense, due to the underlying mechanics.
Description
The pointer input API needs improvement: