Clickable View in Compose LazyColumn consumes scroll event

Viewed 565

I've a Compose LazyColumn which contains AndroidViews each of which contains clickable and non-clickable views. When scrolling non-clickable area (the TextView view), the LazyColumn can be scrolled. However, when trying to scroll by starting to press down from the clickable area (the Button view), the LazyColumn cannot be scrolled, as if the Button consumes the event without telling the LazyColumn. Is there a workaround for this?

This happens only when using Android View within Compose. However, when the items are Composable instead of View, it works as expected. So does when a clickable Composable is used within a RecyclerView, the clickable Composable doesn't prevent the RecyclerView to scroll.

This is the simple version of what I talk about:

LazyColumn {
    items(100) { idx ->
        AndroidView(
            factory = { ctx ->
                LinearLayout(ctx).apply {
                    orientation = LinearLayout.VERTICAL
                    addView(TextView(ctx).apply {
                        text = "Non-clickable view $idx"
                    })
                    addView(android.widget.Button(ctx).apply {
                        text = "Clickable view $idx"
                        setOnClickListener {}
                    })
                }
            }
        )
    }
}

Compose version: 1.0.5
Kotlin version: 1.5.31

1 Answers

You have two issues. First, you don't have enough items in the list. Your sample code shows only 10 items. If you run that on an average sized phone, there are not enough items to fill the screen to allow for scrolling.

Even after adding more items, you should also set the LazyColumn's width/height. Set it to fillMaxSize, otherwise it defaults to wrapping to the content's width, which in your case is just the width of the button. If you don't fill the width and you only have the buttons in the list, you won't be able to scroll when you scroll outside of the buttons:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        startActivity(intent)

        setContent {
            LazyColumn(modifier = Modifier.fillMaxSize()) {
                items(20) { idx ->
                    AndroidView(
                        factory = { ctx ->
                            LinearLayout(ctx).apply {
                                orientation = LinearLayout.VERTICAL
                                addView(TextView(ctx).apply { text = "Item $idx" })
                                addView(android.widget.Button(ctx).apply { text = "Button"; setOnClickListener {} })
                            }
                        }
                    )
                }
            }
        }
    }
}
Related