Android Jetpack开发 —— ViewModel、LiveData、DataBinding简单使用

前言:

Jetpack网上一搜全都有解释,在这里我就不介绍Jetpack了,直接给 ViewModel、LiveData、DataBinding上例子。

注:本文基于AndroidX的项目,本人自己理解的意思做的讲解,有不对或疑惑的地方欢迎评论留言一起学习探讨。

 

一、ViewModel:

1、功能:屏幕旋转或者字号改变的时候该Activity数据不会丢失。

2、做法:写一个类继承ViewModel:

public class MyViewModel extends ViewModel {

    private int number;

    public int getNumber() {
        return number;
    }

    public void addNumber(int number) {
        this.number += number;
    }
}

3、Activity中:

public class MainActivity extends AppCompatActivity {

    private MyViewModel viewModel ;
    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = findViewById(R.id.textView);
        viewModel = new ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())).get(MyViewModel.class);
        tv.setText(String.valueOf(viewModel.getNumber()));
        
        findViewById(R.id.button).setOnClickListener(v -> {
            //可以给个事件来点击然后这个数值就加2
            viewModel.addNumber(2);
            tv.setText(String.valueOf(viewModel.getNumber()));
        });

此处需要注意,网上的教程甚至官网的教程给viewModel赋值的时候都是用的ViewModelProviders.of(this).get()的方法,但是这个方法已经淘汰了,所以得自己构建这样一个函数,然后又会发现ViewModelProvider(this)这个构造函数并不存在,只有两个参数的构造函数,ctrl+鼠标移到ViewModelProvider上面,可以发现需要一个传一个工厂参数,所以就有了上面这个写法。

 

 

二、LiveData:

1、作用:顾名思义,实时数据,就是数据发生改变的时候,它能自己去修改UI上面上的数据。比如上面我们点击按钮之后还需要手动去给这个textView重新setText。有了这个LiveData,我们就不用每次都给它重新设置值了。

2、做法:在上面这个MyViewModel中做修改:

public class MyViewModel extends ViewModel {

    private MutableLiveData number;

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

    public void addNumber(int number) {
        this.number.setValue(getNumber().getValue() + number);
    }
}

注意:MutableLiveData<这里可以是其他bean对象,但是不能是view或者带Context的东西,因为viewModel的生命周期比Activity或者Fragment长>

3、Activity中给这个数据添加监听:

public class MainActivity extends AppCompatActivity {

    private MyViewModel viewModel ;
    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = findViewById(R.id.textView);
        viewModel = new ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())).get(MyViewModel.class);
        tv.setText(String.valueOf(viewModel.getNumber()));
        
        //这里添加监听
        viewModel.getNumber().observe(this, new Observer() {
            @Override
            public void onChanged(Integer integer) {
                tv.setText(String.valueOf(integer));
            }
        });
        
        findViewById(R.id.button).setOnClickListener(v -> {
            viewModel.addNumber(2);
            //这里去掉了tv的setText
        });
        
        //或者再有其他按钮也同理只做加减不做赋值
        findViewById(R.id.button2).setOnClickListener(v -> {
            viewModel.addNumber(-2);
        });

 

三、DataBinding:

1、作用:数据绑定,有了它,就不用findviewbyid了,甚至你可以不用在Activity里面做setText和setOnClickListener。

2、做法:

     2.1、app的build.gradle里面添加一个声明:

android {
    ......
    defaultConfig {
        ......
        //下面这个添加上
        dataBinding{
            enabled true
        }
    }
    ......
}

     2.2、layout里面的activity_main里面,鼠标移到左边,会有一个灯泡,点击下来点击有data binding字样的那句话,就会得到一个layout的根标签:




    

    

    

        

        

3、这个layout生成了之后它会自动生成一个以这个layout名字命名的类,比如这里是activity_main,就会生成一个ActivityMainBinding的类,然后我们在Activity中使用它:

public class MainActivity extends AppCompatActivity {

    private MyViewModel viewModel ;
    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
//        setContentView(R.layout.activity_main);
        //注意此处把上面这个设置界面的方式换成下面这个,并且赋值给binding
        binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        //然后就可以直接用binding.控件id 来表示该控件。
              
        viewModel = new ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())).get(MyViewModel.class);
        viewModel.getNumber().observe(this, new Observer() {
            @Override
            public void onChanged(Integer integer) {
                //binding.textView表示原先tv对象了
                binding.textView.setText(String.valueOf(integer));
            }
        });
        
        //binding.button代替原先button
        binding.button.setOnClickListener(v -> {
            viewModel.addNumber(2);
        });
        
        binding.button2.setOnClickListener(v -> {
            viewModel.addNumber(-2);
        });

    }

4、这只是初级形态,我们还有个高级一点的。第2步中生成了的layout中有一对标签没有使用,就是标签对。下面我们来使用:

4.1、把viewModel对象搬移到layout的data标签中:


    

4.2、把setText和setOnClickListener搬到layout中:



    

可以看到,格式是“@{}”的形式,里面就是java代码或者landau表达式。

 

4.3、然后修改Activity中代码,可以说是简洁到飞起了:

public class MainActivity extends AppCompatActivity {

    private MyViewModel viewModel ;
    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        viewModel = new ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())).get(MyViewModel.class);
        binding.setViewModel(viewModel); //给layout设置data标签的值
        binding.setLifecycleOwner(this); //这句不能漏,否则不会生效
   }

 

以上就是对ViewModel、LiveData、DataBinding的简单使用。

 

你可能感兴趣的:(Android)