Обмен данными между фрагментами с liveata. но во втором фрагменте данные не соблюдают

Я использую liveata для обмена данными между двумя фрагментами. но данные во втором фрагменте вообще не наблюдаются, поэтому я не могу получить данные.

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

Вскоре данные в первом фрагменте могут быть установлены и наблюдаемы.

первый фрагмент

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

В первом фрагменте данные существуют / наблюдаются

второй фрагмент

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

Во втором фрагменте selectedAttachment вообще не наблюдает (даже tag6 не отлаживается), поэтому я не могу получить данные

Спасибо.


person Alif Al-Gibran    schedule 14.03.2020    source источник
comment
убедиться, что в этих фрагментах используется одна и та же ViewModel?   -  person ॐ Rakesh Kumar    schedule 14.03.2020
comment
да, я использую ту же модель просмотра   -  person Alif Al-Gibran    schedule 14.03.2020


Ответы (2)


SharedViewModel будет работать для вас в этом сценарии. Вы можете использовать следующее:

FirstFragment и то же для 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)
        })
    }

Если на activity это можно использовать следующим образом, если вы наблюдаете на activity

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

Также существует прямая замена ViewModelProvider(this) этим by activityViewModels() < / a> и может быть реализовано как this

person ॐ Rakesh Kumar    schedule 14.03.2020
comment
@ АлифАль-Джебран, как ты использовал ViewModelProvider ?? Пожалуйста, обновите сообщение - person ॐ Rakesh Kumar; 14.03.2020
comment
извините, вы можете описать функцию yourViewModel = ViewModelProvider(it).get(YourViewModel::class.java), потому что я вставил свою переменную модели представления в начале класса, например private val viewModel: ChatListViewModel by inject() - person Alif Al-Gibran; 14.03.2020
comment
вам нужно будет использовать ViewModelProvider со ссылкой activity на fragment, и вот как это работает с SharedViewModel - person ॐ Rakesh Kumar; 14.03.2020
comment
Я думаю, что ваш ответ правильный, но следующая проблема заключается в том, что я объявляю свою модель просмотра как inject (), и многие атрибуты ее используют, поэтому я не могу повторно объявить свою модель просмотра в качестве вашего ответа - person Alif Al-Gibran; 14.03.2020
comment
извините, у меня 1664 строки кода, и многие из них его используют - person Alif Al-Gibran; 14.03.2020

Я меняю метод объявления для объявления модели представления с private val viewModel: ChatListViewModel by inject() на private val viewModel: ChatListViewModel by sharedViewModel<ChatListViewModel>()

person Alif Al-Gibran    schedule 14.03.2020