而且我的数据库有3列杂货ID(长-自动生成),杂货名(字符串)和杂货状态(整数-1/0)。

问题描述 投票:0回答:1
当我不使用LiveData而使用getItemsBasedOnStatus(status:Int)时,便能够检索数据。但是,当它与LiveData包装在一起时,我将得到null。

另一个问题是,当我从数据库中获取项目列表而没有使用LiveData包装并在ViewModel中分配给MutableLiveData时,则所分配的MutableLiveData显示空值。我对此有很多疑问,但没有答案。

为我的viewModel和Fragment添加代码

ViewModel

class GroceryListViewModel( val database: GroceryListDao, application: Application ) : AndroidViewModel(application) { private var viewModelJob = Job() private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob) var grocerylistItems = database.getAllItems() var groceryItem = MutableLiveData<GroceryList>() var groceryitems = MutableLiveData<List<GroceryList>>() init { getAllItemsFromDatabase() } fun insertIntoDatabase(item: GroceryList) { uiScope.launch { insert(item) } } private suspend fun insert(item: GroceryList) { withContext(Dispatchers.IO) { database.insert(item) } } fun updateGrocerylist(itemId: Long, status: Int) { uiScope.launch { groceryItem.value = getItem(itemId) groceryItem.value?.itemStatus = status groceryItem.value?.let { update(it) } } } private suspend fun update(item: GroceryList) { withContext(Dispatchers.IO) { database.update(item) } } private suspend fun getItem(itemId: Long): GroceryList? { return withContext(Dispatchers.IO) { var item = database.getItem(itemId) item } } fun getAllItemsFromDatabase() { uiScope.launch { getAllItems() } } private suspend fun getAllItems() { withContext(Dispatchers.IO) { grocerylistItems = database.getAllItems() } } fun getPendingItemsFromDatabase(status: Int) { uiScope.launch { getPendingItems(status) } } private suspend fun getPendingItems(status: Int) { withContext(Dispatchers.IO) { val items = database.getItemsBasedOnStatus(status) groceryitems.postValue(items) Log.i("Grocery List", "Pending Items:" + items.size) } } fun getDoneItemsFromDatabase(status: Int) { uiScope.launch { getDoneItems(status) } } private suspend fun getDoneItems(status: Int) { withContext(Dispatchers.IO) { val items = database.getItemsBasedOnStatus(status) groceryitems.postValue(items) Log.i("Grocery List", "Done Items:" + items.size) } } fun clearAllItemsFromDatabase() { uiScope.launch { clearItems() } } private suspend fun clearItems() { withContext(Dispatchers.IO) { database.clear() getAllItemsFromDatabase() } } override fun onCleared() { super.onCleared() viewModelJob.cancel() }

}

片段

class GroceryLIstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment val binding = FragmentGroceryLIstBinding.inflate(inflater,container,false) val application = requireNotNull(this.activity).application val dataSource = GroceryDatabase.getInstance(application)?.groceryListDatabaseDao val viewModelFactory = dataSource?.let { GroceryListViewModelFactory(it, application) } val viewModel = viewModelFactory?.let { ViewModelProvider( this, it ).get(GroceryListViewModel::class.java) } viewModel?.grocerylistItems?.observe(this , Observer { binding.grocerylistView.removeAllViews() // is it correct ? for (item in it){ Log.i("Grocery List","Grocery Id=" + item.itemId+" ,Grocery Name=" + item.itemName +", Grocery status="+item.itemStatus) addItemToScrollbar(item, binding, viewModel) } }) binding.addGrocery.setOnClickListener { val imm = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.hideSoftInputFromWindow(view?.windowToken, 0) val item = binding.groceryitemField.text.toString() if (!item.isNullOrBlank()) { val newItem = GroceryList(itemName = item) viewModel?.insertIntoDatabase(newItem) if (viewModel != null) { addItemToScrollbar(newItem, binding,viewModel) } binding.groceryitemField.text.clear() } } binding.doneCheckbox.setOnClickListener { if (binding.doneCheckbox.isChecked) viewModel?.getDoneItemsFromDatabase(1) else viewModel?.getAllItemsFromDatabase() } binding.pendingCheckbox.setOnClickListener { if (binding.pendingCheckbox.isChecked) { viewModel?.getPendingItemsFromDatabase(0) } else viewModel?.getAllItemsFromDatabase() } binding.clearGrocery.setOnClickListener { viewModel?.clearAllItemsFromDatabase() binding.grocerylistView.removeAllViews() } return binding.root } private fun addItemToScrollbar( item: GroceryList, binding: FragmentGroceryLIstBinding, viewModel: GroceryListViewModel ) { val itemBox = AppCompatCheckBox(context) itemBox.text = item.itemName itemBox.isChecked = item.itemStatus == 1 binding.grocerylistView.addView(itemBox) itemBox.setOnClickListener { val itemstatus: Int = if (itemBox.isChecked) 1 else { 0 } viewModel?.updateGrocerylist(item.itemId,itemstatus) } }

}

enter image description here

任何帮助将不胜感激。

我正在使用以下DAO @Dao界面GroceryListDao {@插入有趣的insert(list:GroceryList)@Update fun update(list:GroceryList)@Query(“从杂货清单表中删除”)fun clear()@ ...
android android-room android-livedata
1个回答
0
投票
[如果要在ViewModel中检索数据,则没有viewLifecycleOwner,则可以使用“ observeForever()”,但随后必须显式删除Observer,请参见此answer
© www.soinside.com 2019 - 2024. All rights reserved.