ViewModel、LiveData、Databinding

1.ViewModel
ViewModel 可以用作储存界面数据,取代Bundle savedInstanceState存储数据。ViewModel就是一个存储着我们界面数据的类,界面数据的设定全部来自自定义的ViewModel。

首先,我们需要对某一个界面(例如:MainActivity)设定一个ViewModel(Demo中使用的是MyViewModel 继承自 ViewModel)

我需要对每一个界面定义一个专属的ViewModel,这样易于维护,且代码较为美观;
ViewModel的包为androidx.lifecycle.ViewModel
MainActivity 需要引用包androidx.lifecycle.ViewModelProviders,注意ViewModelProviders后需要有"s",使用时需要添加依赖implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
import androidx.lifecycle.ViewModel;

class MyViewModel extends ViewModel {

private int textViewContent = 0;

int getTextViewContent() {
    return textViewContent;
}

void setTextViewContent(int textViewContent) {
    this.textViewContent = textViewContent;
}

}
接着我们在MainActivity中声明和使用我们针对于该Activity创建的ViewModel

//获取ViewModel类的对象
MyViewModel myViewModel;

//在onCreate()方法中获取ViewModel的具体内容
myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
也就是说以后我们在给控件赋值时只需要获取ViewModel实例中的数值即可,修改数值也是直接修改ViewModel中对应的数值

//修改数值为当前 textViewContent + 1
myViewModel.setTextViewContent(myViewModel.getTextViewContent() + 1);

//给控件赋值为 textViewContent + 1
textView.setText(String.valueOf(myViewModel.getTextViewContent()));

//为了保证每次界面销毁重启后,都可以保存之前的值,我们需要在onCreate()中,给控件赋值为 textViewContent
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
textView = findViewById(R.id.text);
textView.setText(String.valueOf(myViewModel.getTextViewContent()));
}
2、LiveData
LiveData的作用是让底层数据更新时,自动更新界面控件视图,减少手动setText()

同样作为视图数据管理的一个类,LiveData写在ViewModel类中。将被管理的值放于MutableLiveData<>容器中

注意MyViewModel类和MyViewModel类的声明需要是public
注意拓展MutableLiveData<>容器中可以存放多种数据类型List<>、String等等
需要提供修改参数的方法
public class MyViewModel extends ViewModel {

private MutableLiveData textViewContent;
public MyViewModel(){
    textViewContent = new MutableLiveData<>();
    textViewContent.setValue(0);
}

MutableLiveData getTextViewContent() {
    if (textViewContent == null) {
        textViewContent = new MutableLiveData<>();
        textViewContent.setValue(0);
    }
    return textViewContent;
}

void addTextViewContent(int n) {
    textViewContent.setValue(textViewContent.getValue() + n);
}

}

接着在MainActivity中声明控件、声明ViewModel管理类、绑定ViewModel管理类、设置LiveData观察者

点击事件由直接设置控件值变为设置ViewModel对应属性值
控件属性值通过观察者的onChanged()方法设置
代码和视图分离,代码结构更加清晰

public class MainActivity extends AppCompatActivity {

//声明控件
MyViewModel myViewModel;
Button button1, button2;
TextView textView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //绑定视图
    setContentView(R.layout.activity_main);

    //找到控件
    textView = findViewById(R.id.text1);
    button1 = findViewById(R.id.button2);
    button2 = findViewById(R.id.button);

    //绑定ViewModel管理类
    myViewModel = ViewModelProviders.of(this).get(MyViewModelTest.class);

    //设置ViewModel观察者
    myViewModel.getTextViewContent().observe(this, new Observer() {
        @Override
        public void onChanged(Integer integer) {
            textView.setText(String.valueOf(integer));
        }
    });

    button1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            myViewModel.addTextViewContent(1);
        }
    });

    button2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            myViewModel.addTextViewContent(2);
        }
    });
}

}
3、Data Binding
将数据和View绑定,减少声明控件、减少找到控件的过程

data Binding的使用和声明涉及到build.gradle、Java、xml三个部分。

首先在build.gradle中打开dataBinding的开关

dataBinding{
    enabled=true
}

接下来完成Java部分的ViewModel的创建

public class MyViewModel extends ViewModel {

private MutableLiveData textViewContent;

public MyViewModel(){
    textViewContent = new MutableLiveData<>();
    textViewContent.setValue(0);
}

public MutableLiveData getTextViewContent() {
    if (textViewContent == null) {
        textViewContent = new MutableLiveData<>();
        textViewContent.setValue(0);
    }
    return textViewContent;
}

public void addTextViewContent(int n) {
    textViewContent.setValue(textViewContent.getValue() + n);
}

}

在MainActivity中进行控件的绑定、声明

由于在build.gradle中打开了dataBinding的开关,那么我们可以在MainActivity中获取一个类ActivityMainBinding,这个是动态生成的,名称的组合为res-layout-activity_main.xml中.xml文件的名字加上Binding。

binding.setMyViewModel(myViewModel)中的MyViewModel,需要和xml文件中的name属性相对应
public class MainActivity extends AppCompatActivity {

MyViewModel myViewModel;
//声明绑定的xml文件
ActivityMainBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //绑定xml视图文件
    binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    //绑定ViewModel管理类
    myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
    //声明属性(该属性与xml文件中设置的数据name相对应)
    binding.setMyViewModel(myViewModel);
    //声明视图生命周期拥有者
    binding.setLifecycleOwner(this);
}

}
最后修改xml文件内容

使用layout标签包裹整个xml文件
添加data标签
在data标签中添加variable标签来规定使用的数据名、绑定的ViewModel
在xml文件中设置text的属性内容
变量的使用格式为@{name.变量名(可能需要在其中做一些类型转换)}
函数的使用格式为@{()->name.函数(包括参数)}

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">


    




    

    

原文链接:https://www.jianshu.com/p/b35b387ee8d5

你可能感兴趣的:(ViewModel、LiveData、Databinding)