Hir*_*eri 9 android mvvm android-viewmodel
当前需要LifecycleOwner才能使我创建观察者。
我有在ViewModel中创建一个Observer的代码,因此在我的Fragment中检索ViewModel时附加了LifecycleOwner。
根据Google的文档。
警告:ViewModel绝不能引用视图,生命周期或任何可能包含对活动上下文的引用的类。
我是否打破了警告,如果这样做了,您建议我采用哪种方式移动我创建的观察者以返回数据?
我只是做一个观察者,所以我想知道它是否仍然有效。由于在谷歌的文档中也有提及。
ViewModel对象可以包含LifecycleObservers,例如LiveData对象。
主片段
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
}
Run Code Online (Sandbox Code Playgroud)
主视图模型
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
}
Run Code Online (Sandbox Code Playgroud)
更新1:由于@pskink建议使用Transformations,改进了ViewModel。
private lateinit var ipAddress:LiveData<String>
/**
* Improved ViewModel since January 23, 2018 credits to <a href="/sf/users/157698131/">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
}
Run Code Online (Sandbox Code Playgroud)
No. If you wish to observe changes of some LiveData inside your ViewModel you can use observeForever() which doesn't require LifecicleOwner. Remember to remove this observer on ViewModels onCleared() event:
val observer = new Observer() {
override public void onChanged(Integer integer) {
//Do something with "integer"
}
}
Run Code Online (Sandbox Code Playgroud)
...
liveData.observeForever(observer);
Run Code Online (Sandbox Code Playgroud)
...
override fun onCleared() {
liveData.removeObserver(observer)
super.onCleared()
}
Run Code Online (Sandbox Code Playgroud)
Very good reference with examples of observe LiveData.
| 归档时间: |
|
| 查看次数: |
4924 次 |
| 最近记录: |