Android开发经验谈Android开发

Android ViewModel、LiveData

2020-04-13  本文已影响0人  折剑游侠

先搬一下官方介绍

简单来说,ViewModel在屏幕旋转等配置更改期间,对象会保留,储存在ViewModel的数据自然也会保留。LiveData以观察者模式,仅在组件处于激活状态(onStart,onResume)时更新数据,当组件被销毁时,系统会退订它们。一般来讲ViewModel会配合LiveData使用,LiveData初始化在ViewModel中。

下面上代码

build.gradle依赖

dependencies {
    ...
    def lifecycle_version = "2.2.0"

    // ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
    // LiveData
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
}

MainModel

class MainModel : ViewModel() {
    //初始化LiveData,观察的数据类型即泛型String类型
    val contentLiveData: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }
}

MainActivity

class MainActivity : AppCompatActivity() {
    private lateinit var model: MainModel
    private var i = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        //创建ViewModel
        model = ViewModelProvider(this).get(MainModel::class.java)

        //回调方法中更新ui
        val contentObserver = Observer<String> { content ->
            tvContent.text = content
        }

        //订阅
        model.contentLiveData.observe(this, contentObserver)

        //按钮 模拟更新数据操作
        btContent.setOnClickListener {
            i++
            //通过LiveData.setValue()方法通知数据更新,稍后回调Observer接口方法更新ui
            model.contentLiveData.value = "content+$i"
        }
    }
}

ViewModel用于Activity内多个fragment数据共享

FragmentModel

class FragmentModel : ViewModel() {
    val fragmentLiveData: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }
}

FirstFragment

class FirstFragment : Fragment() {
    private lateinit var model: FragmentModel
    private var i = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        model = ViewModelProvider(this).get(FragmentModel::class.java)
    }

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

        btFirst.setOnClickListener {
            i++
            model.fragmentLiveData.value = "content+$i"
        }
    }
}

SecondFragment

class SecondFragment : Fragment() {
    private lateinit var model: FragmentModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        model = ViewModelProvider(this).get(FragmentModel::class.java)

        model.fragmentLiveData.observe(this, Observer { content ->
            tvSecond.text = content
        })
    }

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

同Activity下Fragment获取到的ViewModel实例是同一个,相较于接口回调更简洁。

ViewModel配合协程使用

class MainModel : ViewModel() {
    val contentLiveData: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }

    init {
        viewModelScope.launch {
            val deferred = async(Dispatchers.IO){
                "result"
            }
            val result = deferred.await()

            contentLiveData.value = result
        }
    }
}

Lifecycle配合协程使用

class FirstFragment : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewLifecycleOwner.lifecycleScope.launch {

        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读