Shared ViewModel与Bottom Sheet Dialog Fragment、数据库及UI联动异常
词汇笔记应用RecyclerView无法即时显示新增词汇问题
我开发了一款简易词汇笔记应用,包含2个Fragment与1个主Activity。在HomeFragment中点击addVocabularyButton按钮会弹出BottomSheetDialogFragment,用户输入3项内容后通过Shared ViewModel保存至数据库。目前数据库保存功能正常,但HomeFragment的RecyclerView无法即时显示新增词汇,必须重启应用才能看到。应用使用了Navigation库与RecyclerView。
Home Fragment
class HomeFragment : Fragment() { private var _binding : FragmentHomeBinding? = null private val binding get() = _binding!! private var vocabularyAdapter = VocabulariesHomeAdapter() private lateinit var sharedViewModel: AddVocabularySharedViewModel override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentHomeBinding.inflate(layoutInflater,container, false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) //sharedViewModel = ViewModelProvider(this)[AddVocabularySharedViewModel::class.java] sharedViewModel = (activity as MainActivity).sharedViewModel sharedViewModel.getAllVocabulariesFromDB() observeAllVocabularies() prepareRecyclerView() addVocabularyOnClick() vocabularyAdapter.onItemDeleteClicked = { sharedViewModel.deleteVocabulary(it) observeAllVocabularies() } } private fun prepareRecyclerView(){ binding.recyclerViewHome.apply { layoutManager = LinearLayoutManager(context) adapter = vocabularyAdapter } } private fun addVocabularyOnClick(){ binding.addVocabularyButton.setOnClickListener{ val action = HomeFragmentDirections.actionHomeFragmentToAddVocabularyBottomSheetFragment() Navigation.findNavController(it).navigate(action) } } private fun observeAllVocabularies(){ sharedViewModel.allVocabulariesLiveData.observe(viewLifecycleOwner, Observer { vocabularyAdapter.updateVocabularyList(it) }) } }
Dialog Fragment
class AddVocabularyBottomSheetFragment : BottomSheetDialogFragment() { private var _binding : FragmentAddVocabularyBottomSheetBinding? = null private val binding get() = _binding!! private lateinit var sharedViewModel: AddVocabularySharedViewModel private var vocabularyInput : String? = null private var translationInput : String? = null private var sampleSentenceInput : String? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentAddVocabularyBottomSheetBinding.inflate(layoutInflater,container,false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) //sharedViewModel = ViewModelProvider(this)[AddVocabularySharedViewModel::class.java] sharedViewModel = (activity as MainActivity).sharedViewModel binding.addOrUpdateVocabularyButton.setOnClickListener { vocabularyInput = binding.vocabularyActualET.text.toString() translationInput = binding.vocabularyTranslationET.text.toString() sampleSentenceInput = binding.vocabularySampleSentenceET.text.toString() val inputVocabulary = Vocabulary(vocabularyInput,translationInput,sampleSentenceInput) insertVocabularyToDB(inputVocabulary) sharedViewModel.getAllVocabulariesFromDB() dismiss() } } private fun insertVocabularyToDB(vocabulary: Vocabulary){ sharedViewModel.insertVocabulary(vocabulary) } }
Shared ViewModel
class AddVocabularySharedViewModel(application: Application) : AndroidViewModel(application) { private var _allVocabulariesLiveData = MutableLiveData<List<Vocabulary>>() private var _vocabularyLiveData = MutableLiveData<Vocabulary>() val allVocabulariesLiveData get() = _allVocabulariesLiveData val vocabularyLiveData get() = _vocabularyLiveData val dao = VocabularyDatabase.makeDatabase(application).vocabularyDao() val repository = VocabularyRepository(dao) fun insertVocabulary(vocabulary: Vocabulary) = CoroutineScope(Dispatchers.IO).launch { repository.insertVocabulary(vocabulary) } fun updateVocabulary(vocabulary: Vocabulary) = CoroutineScope(Dispatchers.IO).launch { repository.updateVocabulary(vocabulary) } fun deleteVocabulary(vocabulary: Vocabulary) = CoroutineScope(Dispatchers.IO).launch { repository.deleteVocabulary(vocabulary) } fun getAllVocabulariesFromDB() = CoroutineScope(Dispatchers.IO).launch { val temp = repository.getAllVocabulariesFromDB() withContext(Dispatchers.Main){ _allVocabulariesLiveData.value = temp } } fun getVocabularyDetailsByID(vocabularyID : Int) = CoroutineScope(Dispatchers.IO).launch { val temp = repository.getVocabularyDetailsByID(vocabularyID).first() withContext(Dispatchers.Main){ _vocabularyLiveData.value = temp } } }
Adapter
class VocabulariesHomeAdapter : RecyclerView.Adapter<VocabulariesHomeAdapter.VocabulariesHomeViewHolder>() { lateinit var onItemDeleteClicked : ((Vocabulary) -> Unit) val allVocabulariesList = arrayListOf<Vocabulary>() class VocabulariesHomeViewHolder(val binding : RecyclerRowBinding) : RecyclerView.ViewHolder(binding.root) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VocabulariesHomeViewHolder { return VocabulariesHomeViewHolder(RecyclerRowBinding.inflate(LayoutInflater.from(parent.context), parent, false)) } override fun onBindViewHolder(holder: VocabulariesHomeViewHolder, position: Int) { val vocabulary = allVocabulariesList[position] holder.binding.apply { actualWordTV.text = vocabulary.vocabulary translationWordTV.text = vocabulary.vocabularyTranslation deleteButtonRV.setOnClickListener { onItemDeleteClicked.invoke(vocabulary) notifyItemRemoved(position) } } } override fun getItemCount(): Int { return allVocabulariesList.size } fun updateVocabularyList(newList : List<Vocabulary>){ allVocabulariesList.clear() allVocabulariesList.addAll(newList) notifyDataSetChanged() } }
我在使用Bottom Sheet Dialog Fragment时遇到了较大问题,恳请帮助。


内容的提问来源于stack exchange,提问作者Ugur
相关产品推荐
相关产品推荐

