LifecycleOwner в настоящее время нужен мне для создания наблюдателя.
У меня есть код, который создает Observer в ViewModel, поэтому я присоединяю LifecycleOwner при получении ViewModel в моем фрагменте.
Согласно документации Google.
Предупреждение: ViewModel никогда не должен ссылаться на представление, жизненный цикл или любой класс, который может содержать ссылку на контекст действия.
Нарушил ли я это предупреждение, и если да, то каким образом вы порекомендуете мне переместить создание наблюдателя для возврата данных?
Я сделал только наблюдателя, поэтому мне интересно, действительно ли это. Так как также в документации Google это тоже сказано.
Объекты ViewModel могут содержать LifecycleObservers, например объекты LiveData.
MainFragment
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
}
MainViewModel
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. Улучшенная ViewModel благодаря предложению @pskink об использовании преобразований.
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
}
MediatorLiveData
илиTransformations#map
/Transformations#switchMap
? - person pskink   schedule 23.01.2018Transformations
- кажется, это самый простой способ - если нет, то когда дело доходит доMediatorLiveData
, что вы имеете в виду под обоими источниками? есть один источник, который меняется, не так ли? - person pskink   schedule 23.01.2018