探究 jetpack ViewModel、lifecycles、LiveData

簡介:jetpack是一個開發組件工具集,它的主要目的的幫助我們編寫出更加簡潔的代碼,並簡化我們的開發過程

一.ViewModel:專門用來存放與界面相關的數據

ViewModel生命週期比Activity長

/**
 * 基礎的viewModel 用於處理數據和將數據返回給ui層
 */
class MainViewModel(count:Int) : ViewModel() {

    var counter = count

    fun countAdd(){
        counter++
    }
}

/**
 * 可以將值傳給ViewModel,並且構建ViewModel,
 * 因爲在Activity中不能創建ViewModel,因爲ViewModel生命週期比Activity長
 */
class MainViewModelFactory(private val count:Int) : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T = MainViewModel(count) as T
}

class MainActivity : AppCompatActivity() {

    lateinit var viewModel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //得到viewMode
        viewModel = ViewModelProvider(this, MainViewModelFactory(tv.text.toString().toInt())).get(
            MainViewModel::class.java
        )

        tv.setOnClickListener {
            //操作數據
            viewModel.countAdd()
            //得到數據
            tv.text = viewModel.counter.toString()
        }
    }
}

二.Lifecycles:生命週期感知組件

/**
 * 感知生命週期
 *
 * java8的版本 需要在gradle中添加implementation 'android.arch.lifecycle:common-java8:1.1.1'
 */
class MyObserver : DefaultLifecycleObserver {
    val TAG = "MyObserver"

    override fun onCreate(owner: LifecycleOwner) {
        Log.v(TAG,"onCreate")
        Log.v(TAG,"當前生命週期狀態=${owner.lifecycle.currentState.name}")
    }

    override fun onStart(owner: LifecycleOwner) {
        Log.v(TAG,"onStart")
        Log.v(TAG,"當前生命週期狀態=${owner.lifecycle.currentState.name}")
    }

    override fun onResume(owner: LifecycleOwner) {
        Log.v(TAG,"onResume")
        Log.v(TAG,"當前生命週期狀態=${owner.lifecycle.currentState.name}")
    }

    override fun onPause(owner: LifecycleOwner) {
        Log.v(TAG,"onPause")
        Log.v(TAG,"當前生命週期狀態=${owner.lifecycle.currentState.name}")
    }

    override fun onDestroy(owner: LifecycleOwner) {
        Log.v(TAG,"onDestroy")
        Log.v(TAG,"當前生命週期狀態=${owner.lifecycle.currentState.name}")
    }

}


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //添加生命週期組件監聽
        lifecycle.addObserver(MyObserver())
    }

}

三.LiveData:是Jetpack提供的一種響應式編程組件,它可以包含任何類型的數據,並在數據發生變化的時候通知給觀察者。

/**
 * 基礎的viewModel 用於處理數據和將數據返回給ui層
 * 添加liveData 進行響應式監聽
 */
class MainViewModel(count:Int) : ViewModel() {

    val counter :LiveData<Int>
        get() = _counter

    private var _counter = MutableLiveData<Int>()

    init {
        _counter.value = count
    }

    fun countAdd(){
        _counter.value?.plus(1)
    }
}



class MainActivity : AppCompatActivity() {

    lateinit var viewModel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //得到viewMode
        viewModel = ViewModelProvider(this, MainViewModelFactory(tv.text.toString().toInt())).get(
            MainViewModel::class.java
        )

        tv.setOnClickListener {
            //操作數據
            viewModel.countAdd()
        }

        viewModel.counter.observe(this, Observer { count->tv.text = count.toString() })
    }
}

map()用於將數據修改成對外的數據格式

/**
 * 基礎的viewModel 用於處理數據和將數據返回給ui層
 * 添加liveData 進行響應式監聽
 * 如果_user本身是個User類型的LiveData,返回需要變成String類型,則需要用到map()
 */
class MainViewModel(user:User) : ViewModel() {

    val user :LiveData<String>
        get() = Transformations.map(_user){
            user->user.toString()
        }

    private var _user = MutableLiveData<User>()

    init {
        _user.value = user
    }

    fun countAdd(){
        _user.value?.apply {
            User(this.userName,this.phone+1,this.address)
        }
    }
}

switchMap():如果ViewModel中的某個LiveData對象需要調用另外的方法獲取,那麼我們就可以藉助switchMap()方法,將LiveData轉化成可觀察的對象


/**
 * 基礎的viewModel 用於處理數據和將數據返回給ui層
 * 添加liveData 進行響應式監聽
 * switchMap()將Repository中的
 */
class MainViewModel(user:User) : ViewModel() {

    val user : LiveData<User>?
        get() = Transformations.switchMap(_user){
            user->Repository.getUser(user)
        }

    private var _user = MutableLiveData<String>()

    //此處調用是爲了讓Transformations.switchMap運行 這樣就可以觀察Repository中的liveData
    init {
        _user.value = user.userName
    }

}


object Repository {

    fun getUser(userId:String) :LiveData<User>{
        val liveData = MutableLiveData<User>()
        liveData.value = User(userId, "", "0")
        return liveData
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章