笔记03:RecyclerView相关列表项的小bug修复和需求实现
2026/6/3 20:07:26 网站建设 项目流程

bug1:文本框宽度设置wrap_content时显示不全

解决:约束布局规定尾部对齐,同时设置宽度为0dp

<TextView ... android:layout_width="0dp" android:layout_height="wrap_content" ... app:layout_constraintEnd_toEndOf="parent" />

bug2:RecyclerView使用分页查询数据,首次进入界面列表项自动滚至首页底部

修复后 ->

解决:移除RecyclerView默认设置的动画

binding.recyclerView.itemAnimator = null

需求1:底部导航消息通知图标红点

mainViewmodel定义livedata用于获取红点显示与否:

private val _showDot = savedStateHandle.getLiveData("showDot", false) val showDot = _showDot.distinctUntilChanged() fun updateDot(show: Boolean) { _showDot.value = show }

mainActivity订阅showDot,定义底部徽章对应的ItemId,颜色以及显隐:
参考文档:https://github.com/material-components/material-components-android/blob/master/docs/components/BottomNavigation.md

vm.showDot.observe(this) { val bottomDot = binding.bottomNavigationView.getOrCreateBadge(itemId) bottomDot.backgroundColor = ContextCompat.getColor(this, R.color.dot) bottomDot.isVisible = it }

列表viewmodel定义livedata用于获取列表项数据:

// 用于内部数据设置 private val _data = MutableStateFlow<List<T>>(emptyList()) // 暴露给外部,仅可获取 val data = _data.asLiveData(coroutineContext)

列表fragment观察data根据列表项已读情况调用mainViewmodel的方法:

private fun setBottomDot() { vm.data.observe(this) { data -> val aItem = data.firstOrNull() as? ListItem.AItem val bList = data.map { it as? ListItem.BItem } val show = aItem?.showDot == true || bList.any { it?.status == ListDetails.Status.UNREAD } mainVm.updateDot(show) } }

实现效果

需求2:返回时更新列表常驻项图标红点显示(AItem点击后会跳转到A数据列表页面fragment2)

fragment2中检查列表项已读情况,在返回时调用:

private fun checkRead() { val hasUnread = adapter.items.any { it.status == ListDetails.Status.UNREAD } val result = bundleOf(HAS_UNREAD to hasUnread) parentFragmentManager.setFragmentResult(SHOULD_SHOW_DOT, result) }

fragment1设置监听器进行获取和处理:

private fun setAItemDot() { parentFragmentManager.setFragmentResultListener( SHOULD_SHOW_DOT, this ) { requestKey, resultBundle -> if (requestKey == SHOULD_SHOW_DOT) { val hasUnread = resultBundle.getBoolean(HAS_UNREAD) val item = adapter.getItem(A_ITEM) as? ListItem.AItem ?: return@setFragmentResultListener val updatedItem = item.copy(showDot = hasUnread) adapter[A_ITEM] = updatedItem adapter.notifyItemChanged(A_ITEM) } } }

实现效果

全部已读 ->

通过Bundle传递数据对象需实现Parcelable接口,@Parcelize注解修饰,依赖导入:

// libs.versions.toml [versions] kotlin = "your version" ... [plugins] kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } // build.gradle.kts(:Project) plugins { ... alias(libs.plugins.kotlin.android) apply false } // build.gradle.kts(:app) plugins { ... alias(libs.plugins.kotlin.android) id("kotlin-parcelize") }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询