LifeCycle,ViewModel(LiveData),DataBinding

LifeCycle,ViewModel(LiveData),DataBinding


前言

记录安卓学习的每一天


一、LifeCycle

这个我就不讲了,也讲不清楚哈哈哈

二、ViewModel(LiveData)先引入依赖

这是一个好东西,具体好在哪里呢,比如说,我们在手机翻转屏幕的时候呢,如果不ongoingonCreate里的那个Bundle savedInstanceState来做一个缓存,就会导致数据丢失,这是一个很麻烦的事情,然而这个ViewModel(LiveData)就强大了,他独立出来,用来管理界面上零时的一些缓存数据,这种解耦不仅方便,而且提供程序的可操作性,后期的维护什么的都比较方便。
在这里插入图片描述
我一般习惯用搜索的方式添加依赖,这样一般搜到的都是最新的

1.创建一个自定义类来继承ViewModel

代码如下(示例):
//这里演示用法,内部就只增加一个int类型的number。

public class myViewModel extends ViewModel {
    //这个ViewModel类是用来管理的数据的
    public int number = 0;
}

2.修改活动中的代码

注意原有的绑定ViewModel方式被废弃了,这里采用最新的
代码如下(示例):

viewModel = new ViewModelProvider(this).get(myViewModel.class);

3.给一个简单的xml文件,两个button来操作数,一个TextView来显示数

在这里插入图片描述
代码我就不贴了

4.最后修改活动中的整体代码如下

public class MainActivity extends AppCompatActivity {

    private myViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewModel = new ViewModelProvider(this).get(myViewModel.class);
        TextView textView = findViewById(R.id.textView);
        textView.setText(String.valueOf(viewModel.number));//暂时保存数据

        Button add = findViewById(R.id.add);
        Button del = findViewById(R.id.del);

        add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                viewModel.number++;
                textView.setText(String.valueOf(viewModel.number));
            }
        });

        del.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                viewModel.number --;
                textView.setText(String.valueOf(viewModel.number));
            }
        });
    }
}

这样就完成了,ViewModel的基本使用就是这个样子啦,是不是很简单

三,DataBinding

要是说ViewModel是好东西,那这个DataBinding也一定是好东西,而且非常好,真的,他是干嘛的呢,我们再每次一使用控件,总是需要绑定对吧,“方的为由拜爱地”有时候要写个十几几十个,对吧吗,直接吐血,那有了这个DataBinding之后就再也不用写“方的为由拜爱地”了哈哈哈哈哈
在此之前,我们修改一下上面的代码

public class myViewModel extends ViewModel {

    //定义一个活着的数据,并指定类型
    private MutableLiveData<Integer> number;//MutableLiveData的父类是LiveData,这样就可以添加观察了

    //为这个活着的数据添加一个getNumber方法,以便在活动中得到这个数据并且为其添加观察
    public MutableLiveData<Integer> getNumber(){
        if(number==null){
            number = new MutableLiveData<>();
            number.setValue(0);
        }
        return number;
    }

    //这里我们继续将对数据的操作方法独立出来,进一步解耦
    public void add(){
        number.setValue(number.getValue()+1);
    }

    public void del(){
        number.setValue(number.getValue()-1);
    }
}
public class MainActivity extends AppCompatActivity {

    private myViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView textView = findViewById(R.id.textView);
        Button add = findViewById(R.id.add);
        Button del = findViewById(R.id.del);

        viewModel = new ViewModelProvider(this).get(myViewModel.class);
        //先得到数据,再添加一个观察
        viewModel.getNumber().observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {
                textView.setText(String.valueOf(integer));
            }
        });

        add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                viewModel.add();
            }
        });

        del.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                viewModel.del();
            }
        });
    }
}

相应的都给出了注释,你会发现代码再一次清晰明了,简洁了,我们不用总对TextView进行操作,只需要添加观察就行了,对吧。
好的,下面就开始重点了,DataBinding了

1.先在manifest中去声明

    defaultConfig {
        applicationId "com.example.viewmoder"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        //下面这两行是增加的
        dataBinding{
            enabled true
        }
    }

2.接着我们转到布局文件xml

在这里插入图片描述
点击这个图片的小灯泡,选择convert to data binding layout,会出现下面这样

这时候我们回到活动中,活动中或多了一个类型,ActivityMainBinding,接着通过这句话

ActivityMainBinding mainBinding;
 mainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);

代替setContentView(R.layout.activity_main);这样我们就不再需要写“方的为由拜爱地”了,可以直接通过
对象mainBinding来调用
示例代码

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding mainBinding;
    private myViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);

        viewModel = new ViewModelProvider(this).get(myViewModel.class);
        //添加一个观察
        
        viewModel.getNumber().observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {
                mainBinding.textView.setText(String.valueOf(integer));
            }
        });

        mainBinding.add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                viewModel.add();
            }
        });

        mainBinding.del.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                viewModel.del();
            }
        });
    }
}

是不是很爽,对吧,如果你觉得这就没了,真就大错特错了,他还可以反向绑定,

3.反向绑定

回到上面的图,点击小灯泡之后自动生成了这个标签,这个就是用来声明这个额xml文件要和那个java代码绑定的意思,看操作吧

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>======================改动处
        <variable
            name="data"
            type="com.example.viewmoder.MyViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <Button
            android:id="@+id/del"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->data.del()}"======================改动处
            android:text="@string/del"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/add"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.825" />

        <Button
            android:id="@+id/add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/add"
            android:onClick="@{()->data.add()}"======================改动处
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/del"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.825" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.60601914" />

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(data.number)}"======================改动处
            android:textSize="48sp"
            app:layout_constraintBottom_toTopOf="@+id/guideline2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.498"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.257" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

主活动

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding mainBinding;
    MyViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //加载布局进活动
        mainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        //实例化viewModel来缓存数据
        viewModel = new ViewModelProvider(this).get(MyViewModel.class);
        //设置反向绑定的viewModel类
        mainBinding.setData(viewModel);
        //将反向绑定设置为自我监听
        mainBinding.setLifecycleOwner(this);
    }
}

当主活动减少到这个地步,我人都傻了,说实话目前的我觉得反向绑定并不好用,因为代码逻辑都不清楚了,后期改不能跑到xml文件中去修改代码吧,咱也不敢说呀是不是,先记录一手吧。

总结

记录一下吧,MVVM模式,说实话有点过于强大了


版权声明:本文为weixin_45408679原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。