Android/Kotlin中MutableList为空时如何修改TextView的可见性
问题原因及修复方案
1. ViewModel中修改列表未触发LiveData通知
直接修改MutableLiveData持有的MutableList内容不会触发LiveData的变更回调,因为LiveData检测的是持有的对象引用是否变化,不是对象内部内容是否变化,所以你的Observer根本收不到列表更新的事件。
修改后的ViewModel代码如下:
val entryList: MutableLiveData<MutableList<Entry>> get() = _entryList init { _entry = MutableLiveData<Entry>() _entryList.value = mutableListOf() } // 修改addEntry方法 fun addEntry(entryInfo: Entry){ _entry.value = entryInfo // 新建列表赋值,触发LiveData的变更通知 val newList = _entryList.value?.toMutableList() ?: mutableListOf() newList.add(entryInfo) _entryList.value = newList }
2. Observer中操作了无效的View实例
你在Observer里重新inflate出来的entryListView是全新的View实例,和当前Fragment已经渲染在屏幕上的布局完全无关,修改这个新实例的TextView可见性当然不会生效,应该直接用Fragment初始化好的binding对象操作当前显示的控件。
修改后的Observer代码如下:
Observer { entryList -> // 直接用Fragment全局的binding对象操作当前显示的控件,不要重复inflate布局 binding.instructions_text_view.visibility = if (entryList.isNullOrEmpty()) { View.VISIBLE } else { View.GONE } // 先清空旧条目,避免重复添加 binding.entryList.removeAllViews() entryList.forEach { entry -> val itemView = inflater.inflate(R.layout.entry_list_item, null, false) itemView.date_entry_text_view.text = String.format(getString(R.string.date), entry.date) // 你原代码这里漏了卡路里的赋值,补上对应逻辑即可 itemView.calories_entry_text_view.text = String.format(getString(R.string.calories), entry.calories) binding.entryList.addView(itemView) } }
补充注意事项
- 给LiveData设置观察者时,lifecycleOwner请传
viewLifecycleOwner,不要传Fragment自身,避免Fragment退到后台时收到无效回调 - 确保你在Fragment的
onCreateView中已经正确初始化了ViewBinding,不要在Observer中重复inflate根布局
内容的提问来源于stack exchange,提问作者Marina8
相关产品推荐
相关产品推荐

