Mik*_*ike 16 android scroll bottom-sheet android-jetpack-compose lazycolumn
我使用LazyColumn
inside BottomSheetDialogFragment
,但如果LazyColumn
向上滚动列表,则Bottom
工作表对话框将滚动而不是LazyColumn
列表。似乎BottomSheetDialogFragment
拦截用户触摸输入。
看起来就是这样:
LazyColumn
里面如何正确使用BottomSheetDialogFragment
?
MyBottomSheetDialogFragment.kt:
class MyBottomSheetDialogFragment : BottomSheetDialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return ComposeView(requireContext()).apply {
setContent {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("Header", color = Color.Black)
LazyColumn(
Modifier
.weight(1f)
.fillMaxWidth()) {
items(100) {
Text("Item $it", Modifier.fillMaxWidth(), Color.Black)
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
并使用以下代码显示它:
MyBottomSheetDialogFragment().show(activity.supportFragmentManager, null)
Run Code Online (Sandbox Code Playgroud)
当我们使用 XMLRecyclerView
列表时,要解决这个问题,我们必须使用此处描述的方式包装RecyclerView
列表,但是如何使用 Jetpack Compose 解决它?NestedScrollView
ikn*_*now 23
由于组合问题可以通过使用RememberNestedScrollInteropConnection1.2.0-beta01
来解决
:
Modifier.nestedScroll(rememberNestedScrollInteropConnection())
Run Code Online (Sandbox Code Playgroud)
就我而言,它BottomSheetDialogFragment
是标准的View
,并且带有ComposeView
id container
。在onViewCreated
我做的:
binding.container.setContent {
AppTheme {
Surface(
modifier = Modifier.nestedScroll(rememberNestedScrollInteropConnection())
) {
LazyColumn {
// ITEMS
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在列表正在以正确的方式滚动。
我找到了这个问题的一个很好的答案。我们可以使用 Kotlin 扩展在 Android 视图上使用 Jetpack Compose 底部工作表。
有关其工作原理的更多详细信息请参见此处。
这是我们需要的所有代码:
// Extension for Activity
fun Activity.showAsBottomSheet(content: @Composable (() -> Unit) -> Unit) {
val viewGroup = this.findViewById(android.R.id.content) as ViewGroup
addContentToView(viewGroup, content)
}
// Extension for Fragment
fun Fragment.showAsBottomSheet(content: @Composable (() -> Unit) -> Unit) {
val viewGroup = requireActivity().findViewById(android.R.id.content) as ViewGroup
addContentToView(viewGroup, content)
}
// Helper method
private fun addContentToView(
viewGroup: ViewGroup,
content: @Composable (() -> Unit) -> Unit
) {
viewGroup.addView(
ComposeView(viewGroup.context).apply {
setContent {
BottomSheetWrapper(viewGroup, this, content)
}
}
)
}
@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun BottomSheetWrapper(
parent: ViewGroup,
composeView: ComposeView,
content: @Composable (() -> Unit) -> Unit
) {
val TAG = parent::class.java.simpleName
val coroutineScope = rememberCoroutineScope()
val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
var isSheetOpened by remember { mutableStateOf(false) }
ModalBottomSheetLayout(
sheetBackgroundColor = Color.Transparent,
sheetState = modalBottomSheetState,
sheetContent = {
content {
// Action passed for clicking close button in the content
coroutineScope.launch {
modalBottomSheetState.hide() // will trigger the LaunchedEffect
}
}
}
) {}
BackHandler {
coroutineScope.launch {
modalBottomSheetState.hide() // will trigger the LaunchedEffect
}
}
// Take action based on hidden state
LaunchedEffect(modalBottomSheetState.currentValue) {
when (modalBottomSheetState.currentValue) {
ModalBottomSheetValue.Hidden -> {
when {
isSheetOpened -> parent.removeView(composeView)
else -> {
isSheetOpened = true
modalBottomSheetState.show()
}
}
}
else -> {
Log.i(TAG, "Bottom sheet ${modalBottomSheetState.currentValue} state")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)