Android APP開發中,開發者們都想有一個公共的組件,能夠實現後臺數據的監聽,同時實時更新到UI進行顯示,從而大大簡化開發過程。Google針對這一開發需求,提供了Jetpack LiveData組件。下面咱們來一塊兒看下LiveData的基本使用方法吧!android
首先,先了解下使用LiveData的優勢。git
LiveData遵循觀察者模式,實現LifeCycle接口,所以能夠監聽數據的實時更新,感知應用的生命週期,讓開發者可以更多的關注業務具體實現。github
下面咱們來經過一個小Demo來簡單介紹下LiveData的基本使用方法。架構
本例中,數據變化通知UI的顯示由四個控件體現,分別爲:系統時間(Long型)、系統時間、天氣、遠端數據。針對這四個控件的動態顯示,咱們分別來看下其是如何實現的。app
APP首先須要搭建使用LiveData的環境:框架
//app build.gradle dependencies { ... implementation deps.lifecycle.viewmodel_ktx implementation deps.lifecycle.livedata_ktx ... }
class LiveDataViewModel( private val dataSource: DataSource ) : ViewModel() {...}
<layout> <data> <variable name="viewmodel" type="com.android.example.livedatabuilder.LiveDataViewModel" /> </data> ... </layout>
//MainActivity //成員變量 private val viewmodel: LiveDataViewModel by viewModels { LiveDataVMFactory } //onCreate val binding = DataBindingUtil.setContentView<ActivityLivedataBinding>( this, R.layout.activity_livedata ) // Set the LifecycleOwner to be able to observe LiveData objects binding.lifecycleOwner = this // Bind ViewModel binding.viewmodel = viewmodel //LifeDataVMFactory object LiveDataVMFactory : ViewModelProvider.Factory { private val dataSource = DefaultDataSource(Dispatchers.IO) override fun <T : ViewModel?> create(modelClass: Class<T>): T { @Suppress("UNCHECKED_CAST") return LiveDataViewModel(dataSource) as T } }
系統時間的顯示,經過在UI上綁定ViewModel,經過getCurrentTime方法後臺更新、提交數據,來通知UI進行顯示的更新。
ide
//xml <TextView android:id="@+id/time" android:text="@{Long.toString(viewmodel.currentTime)}" .../> //LiveDataViewModel val currentTime = dataSource.getCurrentTime() //DefaultDataSource override fun getCurrentTime(): LiveData<Long> = liveData { while (true) { emit(System.currentTimeMillis())//通知當前系統時間 delay(1000)//延時1秒 } }
系統時間的顯示是根據系統獲取的Long型變量變化映射獲得的,Long值發生變化時,實時更新系統時間顯示。
佈局
//xml <TextView android:id="@+id/time_transformed" android:text="@{viewmodel.currentTimeTransformed}" .../> //LiveDataViewModel 此處有兩種方式實現 //1. currentTime變動後實時通知UI更新 val currentTimeTransformed : LiveData<String> = Transformations.map(currentTime) { Date(it).toString() } //2. 延時500ms後通知 val currentTimeTransformed = currentTime.switchMap { // timeStampToTime is a suspend function so we need to call it from a coroutine. liveData { emit(timeStampToTime(it)) } } private suspend fun timeStampToTime(timestamp: Long): String { delay(500) // Simulate long operation val date = Date(timestamp) return date.toString() }
天氣的顯示經過動態改變數據源提供的數據,從而通知UI顯示(DataSource數據的更新實時經過LiveData傳遞到UI)。
fetch
//xml <TextView android:id="@+id/current_weather" android:text="@{viewmodel.currentWeather}" .../> //LiveDataViewModel val currentWeather: LiveData<String> = liveData { emit(LOADING_STRING) emitSource(dataSource.fetchWeather()) } //DefaultDataSource private val weatherConditions = listOf("Sunny", "Cloudy", "Rainy", "Stormy", "Snowy") override fun fetchWeather(): LiveData<String> = liveData { var counter = 0 while (true) { counter++ delay(2000)//延時兩秒 //按順序循環顯示weatherConditions中的天氣數據信息 emit(weatherConditions[counter % weatherConditions.size]) } }
遠端數據的請求經過Button的點擊事件觸發,數據獲取成功後,通知TextView進行數據顯示。
gradle
//xml <TextView android:id="@+id/cached_value" android:text="@{viewmodel.cachedValue}" .../> <Button android:id="@+id/refresh_button" android:onClick="@{() -> viewmodel.onRefresh()}" .../> //LiveDataViewModel val cachedValue = dataSource.cachedData fun onRefresh() { // Launch a coroutine that reads from a remote data source and updates cache viewModelScope.launch { dataSource.fetchNewData() } } //DefaultDataSource private val _cachedData = MutableLiveData("This is old data") override val cachedData: LiveData<String> = _cachedData override suspend fun fetchNewData() { // Force Main thread withContext(Dispatchers.Main) { _cachedData.value = "Fetching new data..." _cachedData.value = simulateNetworkDataFetch() } } private var counter = 0 // Using ioDispatcher because the function simulates a long and expensive operation. private suspend fun simulateNetworkDataFetch(): String = withContext(ioDispatcher) { delay(3000)//延時3秒 counter++ "New data from request #$counter"//返回此字符串 }
遠端數據的更新流程爲:
將上述四個控件分別綁定對應的LiveData對象,增長其數據變化,就可以實現前文描述的APP動態變化效果了。
幫助文檔
源碼路徑
小技巧: github 代碼下載速度慢,能夠克隆到碼雲上(gitee.com)再下載。
經過這四個控件的LiveData與UI的交互使用,你學會如何使用LiveData了嗎?
歡迎關注公衆號,留言討論更多技術問題