ViewModel
之前写过了LiveData的使用,今天来了解下ViewModel的使用方法。
ViewModel官方说明
先看下官方对它的定义:ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。
可以看出ViewModel就是一个存储数据的类。只是生命周期比较长一点。再借用官网一张图。
可以看出在activity旋转过程中ViewModel是不会被销毁重建的,这就方便了我们广大程序猿了。再也不用去手动保存数据了,而且onSaveInstanceState能够保存的数据类型也是有限的。
使用
下面看看怎么去使用ViewModel,我们就搞简单点,就搞个按钮点击计数。看每次屏幕旋转时候点击次数会不会回到初始值。这里跟LiveData搭配起来使用。
首先先新建一个ViewModel类:
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class DataViewModel extends ViewModel {
//搭配LiveData使用
private MutableLiveData<Integer> data;
public MutableLiveData<Integer> getData() {
if (data == null){
data = new MutableLiveData<>();
//初始值为0
data.setValue(0);
}
return data;
}
}
下面是activity的代码:
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import com.honeywell.livedata.R;
import butterknife.BindView;
import butterknife.ButterKnife;
public class ViewModelActivity extends AppCompatActivity {
private DataViewModel dataViewModel;
@BindView(R.id.tv_data)
public TextView tv_Data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_model);
ButterKnife.bind(this);
dataViewModel = (new ViewModelProvider(this)).get(DataViewModel.class);
dataViewModel.getData().observe(this,(Integer number)->{
tv_Data.setText(number+"");
});
}
public void onClick(View view) {
dataViewModel.getData().setValue(dataViewModel.getData().getValue()+1);
}
}
activity_view_model布局代码:
<?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=".viewmodel.ViewModelActivity">
<TextView
android:id="@+id/tv_data"
android:gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="19sp"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/bt_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="add number"
android:gravity="center_horizontal"
android:layout_gravity="center_horizontal"
android:onClick="onClick"/>
</LinearLayout>
代码很简单每次点击按钮时候ViewModle里的数据就进行+1的动作。注意实例化ViewModel的地方有坑,网上很多博客都是写ViewModelProviders.of().get()这种方式,但是发现这种方法已经废弃了。而且谷歌官网也是用的new ViewModelProvider的方式,但是如果直接new的话会提示有错误
Cannot resolve constructor 'ViewModelProvider(包名)'
这时就需要在build.gradle添加
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
下面看看运行的效果
点击按钮,此时点击到了16,然后进行旋转:
可以看到数字还是16,如果换做以前的话肯定此时变成0了。
上面就是ViewModel简单的演示,实际我们更多的将它用在Fragment之间的通信,以前Fragment通信一般都是接口回调或者使用EventBus,现在ViewModel搭配LiveData就能实现Fragment间通信。用完之后发现,嗯,真香。