Compose ModalBottomSheet内Emoji2表情选择器无法滚动的问题求助
问题:AndroidX EmojiPicker在Compose ModalBottomSheet中无法滚动或卡顿
使用AndroidX的emoji2-emojipicker,其XML结构如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/emoji_picker_header" android:layout_width="wrap_content" android:layout_height="@dimen/emoji_picker_header_height" android:paddingEnd="@dimen/emoji_picker_header_padding" android:paddingStart="@dimen/emoji_picker_header_padding" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/emoji_picker_body" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
在Compose中调用的代码:
AndroidView( factory = { context -> EmojiPickerView(context) }, modifier = Modifier .fillMaxWidth() .height(300.dp) )
在Scaffold、Column等普通布局中使用时滚动流畅,但放入ModalBottomSheet这类可滚动Composable后,表情选择器无法滚动。给AndroidView添加verticalScroll(rememberScrollState())修饰符后,虽能滚动但加载卡顿、表情标签功能失效——推测是该修饰符让内部RecyclerView认为高度无限,导致一次性渲染所有表情,无法懒加载。核心问题是RecyclerView嵌套可滚动Composable时,滚动事件传递异常。
解决方案
方案1:让EmojiPicker优先处理滚动事件
给ModalBottomSheet添加嵌套滚动互操作连接,让AndroidView的滚动事件优先被处理,避免被ModalBottomSheet拦截:
ModalBottomSheet( onDismissRequest = { /* 关闭逻辑 */ }, sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true), modifier = Modifier.nestedScroll(rememberNestedScrollInteropConnection()) ) { AndroidView( factory = { context -> EmojiPickerView(context) }, modifier = Modifier.fillMaxWidth().height(300.dp) ) }
此方案适用于ModalBottomSheet不需要整体滚动的场景,保留EmojiPicker自身的懒加载和滚动流畅性。
方案2:禁用EmojiPicker内部RecyclerView的嵌套滚动
在创建EmojiPickerView时,手动关闭内部RecyclerView的嵌套滚动功能,避免滚动事件被外部Composable拦截:
AndroidView( factory = { context -> EmojiPickerView(context).apply { findViewById<RecyclerView>(R.id.emoji_picker_body)?.isNestedScrollingEnabled = false findViewById<RecyclerView>(R.id.emoji_picker_header)?.isNestedScrollingEnabled = false } }, modifier = Modifier.fillMaxWidth().height(300.dp) )
该方案可保留ModalBottomSheet的整体滚动,同时确保EmojiPicker内部RecyclerView保持懒加载,不会卡顿。
方案3:使用Compose原生EmojiPicker(推荐)
直接使用官方提供的Compose版表情选择器,完全适配Compose环境,无View嵌套滚动冲突:
// 依赖:implementation "androidx.emoji2:emoji2-emojipicker-compose:1.4.0" EmojiPicker( onEmojiSelected = { emoji -> /* 处理选中逻辑 */ }, modifier = Modifier.fillMaxWidth().height(300.dp) )
原生Compose实现无需处理跨框架滚动问题,滚动流畅且功能完整。
内容的提问来源于stack exchange,提问作者Giuliopime
相关产品推荐
相关产品推荐

