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



Comments

Popular posts from this blog

Spring Elasticsearch Operations

Hibernate Search - Elasticsearch with JSON manipulation

Today Walkin 14th-Sept