[英]How to change visibility of a TextView if a MutableList is empty? (Android/Kotlin)
I'm working on a simple calorie counter app using two fragments and a ViewModel.我正在使用两个片段和一个 ViewModel 开发一个简单的卡路里计数器应用程序。 I'm a beginner and this is a modification of an app I just created for a course (this app is not a homework assignment).我是初学者,这是对我刚刚为课程创建的应用程序的修改(此应用程序不是家庭作业)。 It uses ViewModel and has a fragment that collects user input and a fragment that displays the input as a MutableList of MutableLiveData.它使用 ViewModel 并有一个用于收集用户输入的片段和一个将输入显示为 MutableLiveData 的 MutableList 的片段。 I would like for the list screen to initially be empty except for a TextView with instructions, and I'd like the instructions to disappear once an entry has been added to the list.我希望列表屏幕最初为空,但带有说明的 TextView 除外,并且一旦将条目添加到列表中,我希望说明消失。 My class instructor told me to use an if-else statement in the fragment with the list to achieve this, but it's not working.我的班主任告诉我在带有列表的片段中使用 if-else 语句来实现这一点,但它不起作用。 He didn't tell me exactly where to put it.他没有告诉我确切地把它放在哪里。 I tried a bunch of different spots but none of them worked.我尝试了很多不同的地方,但没有一个有效。 I don't get errors - just no change to the visibility of the TextView.我没有收到错误 - 只是 TextView 的可见性没有改变。
Here is the code for the ViewModel with the list:这是带有列表的 ViewModel 的代码:
val entryList: MutableLiveData<MutableList<Entry>>
get() = _entryList
init {
_entry = MutableLiveData<Entry>()
_entryList.value = mutableListOf()
}
fun addEntry(entryInfo: Entry){
_entry.value = entryInfo
_entryList.value?.add(_entry.value!!)
}
}
And this is the code for the observer in the list fragment:这是列表片段中观察者的代码:
Observer { entryList ->
val entryListView: View = inflater.inflate(R.layout.fragment_entry_list, null, false)
if (entryList.isNullOrEmpty()) {
entryListView.instructions_text_view.visibility = View.VISIBLE
} else {
entryListView.instructions_text_view.visibility = View.GONE
}
entryList.forEach {entry ->
val view: View = inflater.inflate(R.layout.entry_list_item, null, false)
view.date_entry_text_view.text = String.format(getString(R.string.date), entry.date)
view.calories_entry_text_view.text =
view.line_divider
binding.entryList.addView(view)
}
Thanks for any help.谢谢你的帮助。
I guess you are expecting your observer to get notified of the event when you are adding entryInfo
to your event list ( _entryList.value?.add(_entry.value!!)
. But this won't happen as you are just adding an element to the same mutable list, and as the list reference hasn't changed, live data won't emit any update.我猜您希望您的观察者在您将entryInfo
添加到您的事件列表 ( _entryList.value?.add(_entry.value!!)
时会收到该事件的通知。但这不会发生,因为您只是添加了一个元素到同一个可变列表,并且由于列表引用没有改变,实时数据不会发出任何更新。
To solve this, you have two options.要解决此问题,您有两种选择。
false
, and update it to true
in addEntry()
function.将其初始值设置为false
,并在addEntry()
函数addEntry()
其更新为true
。 Additionally, its generally not a good practice to expose mutable data unless there is no alternative.此外,除非别无选择,否则公开可变数据通常不是一个好习惯。 Here you are exposing a mutable list of Entry and that too in the form of a mutable live data.在这里,您将公开一个可变的 Entry 列表,并且也以可变的实时数据的形式公开。 Ideally, your should be exposing LiveData<List<Entry>>
.理想情况下,您应该公开LiveData<List<Entry>>
。
This is one possible implementation of all the points that I mentioned:这是我提到的所有要点的一种可能实现:
private val _entryList = MutableLiveData(listOf<Entry>()) // Create a private mutable live data holding an empty entry list, to avoid the initial null value.
val entryList: LiveData<List<Entry>> = _entryList // Expose an immutable version of _entryList
fun addEntry(entryInfo: Entry) {
_entryList.value = entryList.value!! + entryInfo
}
I haven't used the _entry
live data here, but you can implement it the same way.我这里没有使用_entry
实时数据,但你可以用同样的方式实现它。
set your viewModel to observe on entry added.将您的 viewModel 设置为在添加条目时观察。
I think you have gotten your visibility toggle in the your if else blocks wrong.我认为您在 if else 块中设置了可见性切换错误。
if (entryList.isNullOrEmpty()) {
entryListView.instructions_text_view.visibility = View.GONE // OR View.INVISIBLE
} else {
entryListView.instructions_text_view.visibility = View.VISIBLE
}
Your Observer should get notified of changes to entryList when _entryList has changed.当 _entryList 发生变化时,您的观察者应该收到 entryList 变化的通知。 Make sure you are calling addEntry() function to trigger the notification.确保您正在调用 addEntry() 函数来触发通知。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.