LiveData和viewModel是Google大佬新推出的开发框架jetpack中的两个组件,对应的是MVVM开发模式。本身来说LiveData和viewModel这两个东西之前也有个人的实现,只不过现在谷歌把这俩组件官方化了,消除差异。(Google教我写代码)
概念这些网上一搜一大把的,这里只是入门一下这两个东西,把最基本的使用说一说,毕竟东西要会用了才能去理解原理。(车都不会开,研究车的发动机有啥用呢)
首先,我们定义MVVM模型中的View层,定义两个Fragment
View层
第一个Fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_marginTop="100dp"
android:id="@+id/text"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
第二个Fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_gravity="center"
android:id="@+id/btn_change"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Model层
然后定义MVVM模型中的Model层,一个LiveData,这个data与第一个fragment的Text有关,我们可以这样定义。
public class MyLiveData extends MutableLiveData<String> {
@Override
protected void onActive() {
//当 LiveData 具有活动状态的 Observer 的时候会调用这个函数。在这个函数中,我们开始监听数据变化。
Log.e("MyLiveData:","call the onActive()");
super.onActive();
}
@Override
protected void onInactive() {
//当 LiveData 没有活动状态的 Observer 的时候会调用这个函数。所以在这个函数中取消更新数据来避免无所谓的耗电。
Log.e("MyLiveData:","call the onInactive()");
super.onInactive();
}
}
这里之所以不继承LiveData<>的原因是,LiveData的setValue方法是protected的,我们无法直接调用它,所以谷歌给我们提供了一个MutableLiveData方法给我们继承。
ViewModel层
最后定义MVVM模型中的ViewModel层,像这样:
public class MyViewModel extends ViewModel {
MutableLiveData<String> liveData = new MyLiveData();
public MutableLiveData<String> getLiveData(){
return liveData;
}
public void change(String s){
getLiveData().setValue(s);
}
@Override
protected void onCleared() {
Log.e("MyViewModel","call the onCleared");
super.onCleared();
}
}
在ViewModel中对数据进行操作,所以将livedata在这里实例化,这里定义一个change方法,表示改变这个text。
最后两个fragment的实现像这样:
public class OneFragment extends Fragment {
private MyViewModel viewModel;
private TextView text;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_one,container,false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
text = (TextView) view.findViewById(R.id.text);
viewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
viewModel.getLiveData().observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
Log.e("cccccc","change");
text.setText(s);
}
});
}
}
第二个Fragment
public class TwoFragment extends Fragment {
private Button btnChange;
private MyViewModel viewModel;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_two,container,false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
btnChange = (Button) view.findViewById(R.id.btn_change);
viewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
btnChange.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewModel.change("改变");
}
});
}
}
类似与观察者模式,监听这个liveData的变化,并对view进行更新。可以看到这里View层(就是这两个fragment)只做展示工作,数据操作的交给viewModel去实现,将逻辑分离了出来。
最后,其实还有一个组件dataBinding用起来更好用,实现了Data和view的双向绑定,大家有空也可以尝试一下。
最后实现结果像这样,点击Button改变另一个fragment中的text