Alif Al-Gibran
Alif Al-Gibran

Reputation: 1246

Sharing data between fragments with livedata. but, in the second fragment data doesn't observe

I'm using livedata to sharing data between two fragments. but, the data in the second fragment doesn't observe at all, so i can't get the data.

ViewModel

    var selectedAttachment = MutableLiveData<ArrayList<Attachment>>()
    private val attachmentList = ArrayList<Attachment>()

    private fun getExistingAttachmentPos(key: String): Int{
        return attachmentList.indexOfFirst { att -> att.name == key}
    }

    fun toggleAttachment(attachment: Attachment){
        val id = attachment.name
        val pos = getExistingAttachmentPos(id)
        if(pos == -1 ){
            attachmentList.add(attachment);
        }else{
            attachmentList.removeAt(pos);
        }
        selectedAttachment.postValue(attachmentList)
    }

Shortly, the data in the first fragment can be set and observable

firstfragment

    private fun observeHorizontalAttachment(){
        viewModel.selectedAttachment.observe(viewLifecycleOwner, Observer<ArrayList<Attachment>>{
            if(it.size>3){
                Log.d("tag63", it.toString())
                wrapPlus3.visibility = View.VISIBLE
                plus3.text = "+${(it.size - 3).toString()}"
                pendingAttachment.clear()
                pendingAttachment.addAll(it)
                (rvAttachment.adapter as AttachmentAdapter).setDataset(it)
            }else{
                pendingAttachment.clear()
                pendingAttachment.addAll(it)
                Log.d("tag3", "kurang dari 3 ${it.size}")
                wrapPlus3.visibility = View.GONE
            }
        })
    }

In the firstfragment data is exist/observable

secondfragment

   private fun attachmentObserve(){
        viewModel.selectedAttachment.observe(viewLifecycleOwner, Observer<ArrayList<Attachment>>{
                Log.d("tag6",  it.toString())
                pendingAttachment.clear()
                pendingAttachment.addAll(it)
        })
    }

    private fun handleRvAttachment(){
        Log.d("tag61",  pendingAttachment.toString())
        rvListAttachment.apply {
            adapter = ListAttachmentAdapter(pendingAttachment)
            layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
        }
    }

In the second fragment the selectedAttachment doesn't observe at all (even 'tag6' doesn't debugged) so I can't get the data

Thanks.

Upvotes: 1

Views: 905

Answers (2)

Alif Al-Gibran
Alif Al-Gibran

Reputation: 1246

I changing the declare method for declaring the view model from private val viewModel: ChatListViewModel by inject() to private val viewModel: ChatListViewModel by sharedViewModel<ChatListViewModel>()

Upvotes: 0

ॐ Rakesh Kumar
ॐ Rakesh Kumar

Reputation: 1314

SharedViewModel will work for you in this scenario. You can use like this following:

FirstFragment and same for SecondFragment

activity?.let {
        yourViewModel = ViewModelProvider(it).get(YourViewModel::class.java)

        yourViewModel.selectedAttachment.observe(viewLifecycleOwner, Observer<ArrayList<Attachment>> {
            Log.d("tag6", it.toString())
            pendingAttachment.clear()
            pendingAttachment.addAll(it)
        })
    }

Where on the activity it can be used as it follows, If you are observing on activity

viewModel = ViewModelProvider(this).get(YourViewModel::class.java)

There is also a direct replacement of ViewModelProvider(this) with this by activityViewModels() and can be implemented like this

Upvotes: 4

Related Questions