2022-11-25

Shared ViewModel Not Working With Bottom Sheet Dialog Fragment, DB and UI

i have a really simple vocabulary note app contains 2 fragment and 1 root activity. In HomeFragment i have a button "addVocabularyButton". When it is clicked a BottomSheetDialogFragment appears and user gives 3 inputs and with a viewmodel it is saved in DB. My problem is when i save the input to the DB it works fine but i cannot see in HomeFragment that word instantaneously. I have to re-run the app to see in home fragment. I am using Navigation library and recycler view in home fragment.

Github link : https://github.com/ugursnr/MyVocabularyNotebook

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()
    }


}

I know there are lots of codes up there but i have a really big problems about using these dialog fragments. Thank you for your help.

enter image description here enter image description here



No comments:

Post a Comment