Android LiveData详解

599 阅读2分钟

一、概念

LiveData是可被观察的数据持有类。具有生命周期(activity、fragment、service)感知的(确保活跃状态下接收data更新)。

二、使用LiveData

LiveData是一个抽象类,它最常见的实现类是MutableLiveData,他其实就是可以在activity、fragment、service处于活跃的时候更新数据。具体需要配合lifecycle使用,这里我现在也一知半解,等到后面自己看了lifecycle相关的内容后会在写一篇更详细的博客,这篇博客只介绍LiveData的基本使用。

1、导入相关的依赖包

implementation "android.arch.lifecycle:extensions:1.1.0"
implementation "android.arch.lifecycle:viewmodel:1.1.0"
implementation "android.arch.lifecycle:livedata:1.1.0"

2、创建一个MutableLiveData对象

 val livedata1 = MutableLiveData<String>()

3、对MutableLiveData对象的value进行赋值

 livedata1.value= SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis())

4、实现观察者

livedata1.observe(this, Observer {
            text1.text=it
        })

我是将这个LiveData在fragment里面实现,然后在activity里面实现添加和移除fragment的方法来观察随着fragment生命周期变化该TextView值的变化。

下面附上所有代码,都有很清楚的注释。

activity代码:

import android.annotation.SuppressLint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.MutableLiveData
import kotlinx.android.synthetic.main.activity_main.*
import java.text.SimpleDateFormat

class MainActivity : AppCompatActivity() {
    @SuppressLint("ResourceType")
    val livedata=MutableLiveData<UserData>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var sdf=SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        var timeformat=sdf.format(System.currentTimeMillis())
        var user1=UserData("张三",987654321)
        livedata.value=user1
        //当数据变化时会回调这个观察者
        livedata.observe(this, androidx.lifecycle.Observer {
            name.text=user1.name1
            phone.text=user1.phone1.toString()
        })
        val appfragment = FirstFragment()
        supportFragmentManager.beginTransaction()
            .add(R.id.fragment, appfragment)
            .commit()
        addfra.setOnClickListener {
            supportFragmentManager.beginTransaction()
                .attach(appfragment)//显示fragment,可以用show,但是show()不会改变fragment的生命周期
                .commit()
        }
        deletefra.setOnClickListener {
            supportFragmentManager.beginTransaction()
                .detach(appfragment)//隐藏fragment,可以用hide,但是hide()不会改变fragment的生命周期
                .commit()
        }

        update.setOnClickListener {
            //改变数据,自动回调上面的observe
            user1= UserData("大辉大辉",123456789)
            livedata.postValue(user1)
        }
    }

}

activity布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_gravity="center_horizontal"
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:layout_gravity="center_horizontal"
        android:id="@+id/phone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <FrameLayout
        android:id="@+id/fragment"
        android:layout_width="match_parent"
        android:layout_height="200dp" />

    <Button
        android:id="@+id/addfra"
        android:layout_marginTop="35dp"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="添加fragment" />
    <Button
        android:id="@+id/deletefra"
        android:layout_marginTop="30dp"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="移除fragment"/>

    <Button
        android:id="@+id/update"
        android:layout_marginTop="35dp"
        android:text="变更数据"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

fragment代码

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import kotlinx.android.synthetic.main.fragment_first.view.*
import java.text.SimpleDateFormat
class FirstFragment : Fragment() {
   
    lateinit var text1: TextView
    val livedata1 = MutableLiveData<String>()
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_first, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        livedata1.value = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis())
        livedata1.observe(this, Observer {
            text1.text = it
        })

    }

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

fragment布局代码

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#CCC"
    tools:context=".FirstFragment">
    <TextView
        android:gravity="center"
        android:id="@+id/text1"
        android:textColor="#000"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />
</FrameLayout>

数据类UserData

class UserData(name: String, phone: Long) {
    var name1 = name
    var phone1 = phone
}

这只是LiveData的入门级操作,还有很多高深的应用,比如map实现数据转换,搭配lifecycle的使用,有问题欢迎留言讨论等.