未设置LiveData,从未调用观察者

时间:2019-01-16 20:15:18

标签: android mvvm kotlin android-livedata

我正在尝试在我的MainViewModel中保存一个“情节”,并允许其他Fragments通过该ViewModel来访问它。

MainActivity中,我观察到ViewModel中的更改从未被触发。奇怪的是,它对我的​​MainFeed RSS对象工作正常

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    mViewModel = ViewModelProviders.of(this, mViewModelFactory).get(MainViewModel::class.java)


    mViewModel?.getMainFeed()

    setFragment(EpisodesFragment(), false)

    mViewModel?.episode?.observe(this, Observer {
        Log.d(TAG, "HERE 123")
    })
}

这里是MainViewModel

class MainViewModel @Inject constructor(): ViewModel() {
    val TAG: String? = MainViewModel::class.simpleName

    @Inject lateinit var api: NetworkModule

    var mainFeed: MutableLiveData<Response<RSS>> = MutableLiveData()
    var episode: MutableLiveData<Item> = MutableLiveData()

    companion object{
        fun create(activity: FragmentActivity, viewModelFactory: ViewModelProvider.Factory): MainViewModel {
            return ViewModelProviders.of(activity, viewModelFactory).get(MainViewModel::class.java)
        }
    }

    fun getMainFeed(){
        GlobalScope.launch(Dispatchers.Main) {
            val request = api.getRssFeed()
            val response = request.await()

            if(response.isSuccessful){
                Log.d(TAG, "isSuccessful")

                mainFeed.value = response
            } else {
                Log.d(TAG, "not successful")
            }
        }
    }

    fun setEpisode(item: Item?){
        Log.d(TAG, item?.description)
        episode?.value = item
    }
}

在我的EpisodesFragment中,我正在将MainViewModel传递给RecyclerView适配器。在“情节”项目的布局中,我有一个onClick(),它调用mViewModel.setEpisode(episode)

因此,点击次数正在增加。我设置了断点,可以看到情节项目实际上在那里,并在setEpisode()方法中保存了数据。实际上,它从来没有在LiveData中设置。我验证了ViewModel在我使用过的任何位置都不为空。

编辑:为EpisodesFragment添加代码

class EpisodesFragment @Inject constructor() : DaggerFragment() {
    var TAG: String? = EpisodesFragment::class.simpleName

    var mBinding: FragmentEpisodesBinding? = null
    var mRV: RecyclerView? = null
    var mAdapter: EpisodesRecyclerViewAdapter? = null

    var mItems: MutableList<Item> = ArrayList<Item>()

    @Inject
    lateinit var mViewModelFactory: ViewModelProvider.Factory
    var mViewModel: EpisodesViewModel? = null
    var mMainViewModel: MainViewModel? = null

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        super.onCreateView(inflater, container, savedInstanceState)

        mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_episodes, container, false)
        mBinding?.executePendingBindings()


        return mBinding?.root
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        mViewModel = ViewModelProviders.of(this,
            mViewModelFactory
        ).get(EpisodesViewModel::class.java)

        mMainViewModel = ViewModelProviders.of(
            this,
            mViewModelFactory
        ).get(MainViewModel::class.java)

        if (mBinding?.rv != null) {
            mRV = mBinding?.rv
            val context: Context? = mRV?.context

            mRV?.setHasFixedSize(true)

            mAdapter = EpisodesRecyclerViewAdapter(mMainViewModel)

            mRV?.adapter = mAdapter

            val layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
            val dividerItemDecoration = DividerItemDecoration(
                mRV?.context,
                layoutManager.orientation
            )
            mRV?.addItemDecoration(dividerItemDecoration)
            mRV?.layoutManager = layoutManager

        }

        mViewModel?.getMainFeed()

        mViewModel?.mainFeed?.observe(viewLifecycleOwner, Observer {
            mItems.addAll(it?.body()?.channel?.item!!)

            Log.d(TAG, mItems.get(0).description)
            mAdapter?.setItems(mItems)
            mAdapter?.notifyDataSetChanged()
        })
    }
}

1 个答案:

答案 0 :(得分:1)

在请求activity时,尝试在this中使用EpisodesFragment属性而不是MainViewModel

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    mMainViewModel = ViewModelProviders.of(
        activity,
        mViewModelFactory
    ).get(MainViewModel::class.java)

    // ...
}

ViewModelProviders.of可能会返回不同的MainViewModel实例作为片段。