我第一次嘗試在 Android 中LiveData使用ViewModels。MutableLiveData我還沒有閱讀所有檔案。
我的問題:
從外部(從 a )更改fun applyFilters()時如何呼叫。val filterByName = MutableLiveData<String>()Fragment
在 .NET MVVM 中,我只需在filterByName屬性的設定器中添加該呼叫。但是我該怎么做呢MutableLiveData?
我想我應該使用MediatorLiveData,但是這個檔案并沒有解釋太多。
我正在考慮使用observer內部視圖模型(以便它可以觀察自己),但是我必須使用AndroidViewModel而不是ViewModel, 來獲得lifecycleOwner觀察 Mu??tableLiveData 所需的...
我的代碼:
在我的AssignUhfTagToInventoryItemViewModel() : ViewModel()(在幾個片段之間共享)我有這樣的屬性:
/* This is filled only once in SomeViewModel.init() function, always contains all data */
var _items = ArrayList<InventoryItemDto?>()
/* This is filled from _items, contains filtered data */
val items = MutableLiveData<ArrayList<InventoryItemDto?>>().apply { value = ArrayList() }
val filterByName = MutableLiveData<String>().apply { value = "" }
和這樣的功能:
fun applyFilters(){
Log.d(TAG, "ViewModel apply filters called. Current name filter: ${filterByName.value}")
items.value?.clear()
val nameFilterLowercase = filterByName.value.toString().lowercase()
if (!filterByName.value.isNullOrEmpty()) {
for (item in _items) {
val itemNameLowercase = item?.name?.lowercase()
if (itemNameLowercase?.contains(nameFilterLowercase) == true)
items.value?.add(item)
}
Log.d(TAG, "Filter is on, data cached : ${_items.count()} rows")
Log.d(TAG, " data displayed: ${items.value?.count()} rows")
}
else {
items.value?.addAll(_items)
Log.d(TAG, "Filter is off, data cached : ${_items.count()} rows")
Log.d(TAG, " data displayed: ${items.value?.count()} rows")
}
}
這是Fragment我使用該視圖模型的一部分:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val binding = FragmentInventoryItemSelectBinding.bind(view)
val vm = ViewModelProvider(requireActivity())[AssignUhfTagToInventoryItemViewModel::class.java]
// old school ArrayAdapter
val listAdapter = InventoryItemViewAdapter(this.context, vm.items.value)
binding.lvItems.adapter = listAdapter // old school ListView
binding.tvFilterByName.addTextChangedListener(AfterTextChangedWatcher {
vm.filterByName.postValue(it)
/*
IN MY FRAGMENT I WANT TO AVOID FUNCTION CALL BELOW
*/
vm.applyFilters()
listAdapter.notifyDataSetInvalidated()
Log.d(TAG, "afterTextChanged: $it")
})
vm.items.observe(requireActivity()){
listAdapter.notifyDataSetInvalidated()
}
}
uj5u.com熱心網友回復:
技術上?我想你可以,但你可以使用Transformations.switchMap從一個 LiveData 獲取輸入并將它們應用到另一個源。
var _items = MutableLiveData(ArrayList<InventoryItemDto?>())
val filterByName = MutableLiveData<String>().apply { value = "" }
val items = Transformations.switchMap(filterByName) { filter ->
val nameFilterLowercase = filter.lowercase()
_items.map { mappedItems ->
mappedItems.filter { listItem ->
listItem.contains(nameFilterLowercase)
}
}
}
vm.items.observe(viewLifecycleOwner) { items ->
// old school ArrayAdapter
val listAdapter = InventoryItemViewAdapter(this.context, items)
binding.lvItems.adapter = listAdapter // old school ListView
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/516816.html
