【Android】ViewModel+LiveData:更加直接地控制视图的方式

LiveData

前言

  ViewModel通过将UI data保存在ViewModel类实例的内部,从而大大地将MVC中的 Controller 与 View 分割开,并且通过ViewModel,我们可以较为方便地解决Activity生命周期发生改变(比如由屏幕旋转引起的生命周期重建)时,UI data的保存以及重现问题。
  下图展示了MVC中Controller与View的关系。简而言之就是,Controller负责处理UI data,通过reference传递给ViewGroup。

初始MVC模型中V与C的关系
  在使用了ViewModel后,Controller与View的关系大致可以用下图中的左半部分表示:

  虽然将UI data交给ViewModel保存处理的方式解决了生命周期变化的问题,但我们仍需要通过Controller传递UI data给View。LiveData的出现,进一步地降低了Controller与View之间地耦合。通过LiveData我们可以不使用Controller,直接将LiveData数据传递给View。如上图右半部分所示。

使用ViewModel+LiveData

  在本例中,我们通过ViewModel+LiveData控制视图中的一个点赞图形,点击点赞图形,视图中的TextView的值便会加一。

Step 1:创建继承自ViewModel类的子类。

package com.hello.livedatatest;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class MyViewModel extends ViewModel {
	/*  MutableLiveData为一种容器,需要按照以下方法创建 */
    private MutableLiveData<Integer> thumbup;
    
    /* MutableLiveData中地数据无法直接赋值,需通过setValue或getaValue赋值或取值 */
    /* 获取thumbup的值 */
    public MutableLiveData<Integer> getThumbup() {
        if (thumbup==null){
            thumbup = new MutableLiveData<>();
            thumbup.setValue(0);
        }
        return thumbup;
    }
    /* thumbup值加一 */
    public MutableLiveData<Integer> setThumbup(){
        thumbup .setValue(thumbup.getValue()+1);
        return thumbup;
    }
}

Step 2:创建实例并绑定,为LiveData创建Ovserve方法

package com.hello.livedatatest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/* 引入ViewModelProviders类,注意同时引入该类所需依赖 */
import androidx.lifecycle.ViewModelProviders;

public class MainActivity extends AppCompatActivity {
    /* 创建实例 */
    MyViewModel myViewModel;
    ImageView imageView;
    TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = findViewById(R.id.imageView);
        textView = findViewById(R.id.textView);
        myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
        /* 为ViewModel中的thumbup数据设置observe,observe的功能为:
            检测数值变化,在底层数据库更改时通知视图 */
        myViewModel.getThumbup().observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {
                textView.setText(String.valueOf(integer));
            }
        });
        /* 为imageView设置onClick功能,每次点击,使TextView数值加一 */
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                myViewModel.setThumbup();
            }
        });
    }
}

Step 3:运行结果

  如下图所示,可正常运行。
在这里插入图片描述

posted @ 2019-07-26 17:56  耶夜夜夜  阅读(1439)  评论(0编辑  收藏  举报