我应该在 ViewModel 中包含 LifecycleOwner 吗? [英] Should I include LifecycleOwner in ViewModel?

查看:65
本文介绍了我应该在 ViewModel 中包含 LifecycleOwner 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前需要 LifecycleOwner 以便我创建观察者.

LifecycleOwner is currently needed in order for me to create an observer.

我有在 ViewModel 中创建观察者的代码,因此在我的 Fragment 中检索 ViewModel 时我附加了 LifecycleOwner.

I have code which creates an Observer in the ViewModel so I attach the LifecycleOwner when retrieving the ViewModel in my Fragment.

根据 Google 的文档.

According to Google's documentation.

注意:ViewModel 绝不能引用视图、生命周期或任何可能包含对活动上下文的引用的类.

Caution: A ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context.

我是否打破了那个警告,如果我打破了,你建议我以什么方式移动我创建的用于数据返回的观察者?

Did I break that warning and If I did, what way do you recommend me to move my creation of an observer for data return?

我只做了一个观察者,所以我想知道它是否仍然有效.因为在 Google 的文档中也有说明.

I only made an observer so I'm wondering if it's still valid. Since also in Google's documentation it also said.

ViewModel 对象可以包含 LifecycleObservers,例如 LiveData 对象.

ViewModel objects can contain LifecycleObservers, such as LiveData objects.

主片段

private lateinit var model: MainViewModel

/**
 * Observer for our ViewModel IpAddress LiveData value.
 * @see Observer.onChanged
 * */
private val ipObserver = Observer<String> {
    textIp.text = it
    hideProgressBar()
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    model = ViewModelProviders.of(this).get(MainViewModel::class.java)
    model.attach(this)
}

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? =
        inflater?.inflate(R.layout.fragment_main, container, false)

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    buttonRetrieveIp.setOnClickListener {
        showProgressBar()
        model.fetchMyIp().observe(this, ipObserver) //Here we attach our ipObserver
    }
}

override fun showProgressBar() {

    textIp.visibility = View.GONE
    progressBar.visibility = View.VISIBLE
}

override fun hideProgressBar() {

    progressBar.visibility = View.GONE
    textIp.visibility = View.VISIBLE
}

主视图模型

private var ipAddress = MutableLiveData<String>()
private lateinit var owner: LifecycleOwner

fun attach(fragment: MainFragment) {
    owner = fragment
}

/**
 * For more information regarding Fuel Request using Fuel Routing and Live Data Response.
 * @see <a href="https://github.com/kittinunf/Fuel#routing-support">Fuel Routing Support</a>
 * @see <a href="https://github.com/kittinunf/Fuel#livedata-support">Fuel LiveData Support</a>
 * */
fun fetchMyIp(): LiveData<String> {

    Fuel.request(IpAddressApi.MyIp())
            .liveDataResponse()
            .observe(owner, Observer {

                if (it?.first?.statusCode == 200) {//If you want you can add a status code checker here.

                    it.second.success {

                        ipAddress.value = Ip.toIp(String(it))?.ip
                    }
                }
            })
    return ipAddress
}

更新 1:由于 @pskink 建议使用转换,改进了 ViewModel.

private lateinit var ipAddress:LiveData<String>

/**
 * Improved ViewModel since January 23, 2018 credits to <a href="https://stackoverflow.com/users/2252830/pskink">pskink</a> <a href="
 *
 * For more information regarding Fuel Request using Fuel Routing and Live Data Response.
 * @see <a href="https://github.com/kittinunf/Fuel#routing-support">Fuel Routing Support</a>
 * @see <a href="https://github.com/kittinunf/Fuel#livedata-support">Fuel LiveData Support</a>
 * */
fun fetchMyIp(): LiveData<String> {

    ipAddress = Transformations.map(Fuel.request(IpAddressApi.MyIp()).liveDataResponse(), {

        var ip:String? = ""

            it.second.success {

                ip = Ip.toIp(String(it))?.ip
            }
        ip
    })

    return ipAddress
}

推荐答案

没有.如果您希望观察 ViewModel 中某些 LiveData 的变化,您可以使用不需要 LifecycleOwnerobserveForever()代码>.

No. If you wish to observe changes of some LiveData inside your ViewModel you can use observeForever() which doesn't require LifecycleOwner.

记得在 ViewModelonCleared() 事件上移除这个观察者:

Remember to remove this observer on ViewModel's onCleared() event:

val observer = new Observer() {
  override public void onChanged(Integer integer) {
    //Do something with "integer"
  }
}

...

liveData.observeForever(observer);

...

override fun onCleared() {
    liveData.removeObserver(observer) 
    super.onCleared()
}

观察 LiveData.

这篇关于我应该在 ViewModel 中包含 LifecycleOwner 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆