ViewModel是什么
ViewModel用来存储和管理UI相关的数据。
ViewModel的功能
用来存储和管理UI相关的数据,当Activity或者Fragment被系统销毁时(例如:发生屏幕转动,低内存时被系统回收)可以保存数据不被销毁;
可以实现Activity和Fragment之间,再加到同一个Activity上的不同Fragment之间的数据通信。
ViewModel的生命周期
下面这张图是左侧是Activity的生命周期右侧是与之对应的Activity中ViewModes的生命周期
viewmodel-lifecycle.png
如何使用ViewModel
1.引入相关依赖到项目中
dependencies {
def lifecycle_version = "1.1.1"
// ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:$lifecycle_version"
// alternatively - just ViewModel
implementation "android.arch.lifecycle:viewmodel:$lifecycle_version" // use -ktx for Kotlin
// alternatively - just LiveData
implementation "android.arch.lifecycle:livedata:$lifecycle_version"
// alternatively - Lifecycles only (no ViewModel or LiveData).
// Support library depends on this lightweight import
implementation "android.arch.lifecycle:runtime:$lifecycle_version"
annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version" // use kapt for Kotlin
// alternately - if using Java8, use the following instead of compiler
implementation "android.arch.lifecycle:common-java8:$lifecycle_version"
// optional - ReactiveStreams support for LiveData
implementation "android.arch.lifecycle:reactivestreams:$lifecycle_version"
// optional - Test helpers for LiveData
testImplementation "android.arch.core:core-testing:$lifecycle_version"
}
2.创建MViewModel类继承系统的AndroidViewModel(ViewModel的子类AndroidViewModel)
package com.architecture.demo.viewModel;
import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.MutableLiveData;
import android.support.annotation.NonNull;
import android.util.Log;
import com.architecture.demo.util.CONSTANT;
import java.util.Map;
public class MViewModel extends AndroidViewModel {
private MutableLiveData<Map<String, String>> mLanguage;
private MutableLiveData<String> mLanguageDes;
public MViewModel(@NonNull Application application) {
super(application);
}
public MutableLiveData<Map<String, String>> getLanguage() {
if (mLanguage == null) {
mLanguage = new MutableLiveData<>();
}
return mLanguage;
}
public MutableLiveData<String> getLanguageDes() {
if (mLanguageDes == null) {
mLanguageDes = new MutableLiveData<>();
}
return mLanguageDes;
}
@Override
protected void onCleared() {
super.onCleared();
Log.i(CONSTANT.TAG_VIEW_MODEL, "PagingViewModel.onCleared");
}
}
3.在Activity中获取MViewModel类的实例
package com.architecture.demo;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.architecture.demo.util.CONSTANT;
import com.architecture.demo.viewModel.Fragment;
import com.architecture.demo.viewModel.Fragment2;
import com.architecture.demo.viewModel.MViewModel;
import java.util.HashMap;
import java.util.Map;
public class ViewModelActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_model);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.frame1, Fragment.getInstance());
fragmentTransaction.add(R.id.frame2, Fragment2.getInstance());
fragmentTransaction.commit();
initViewModel();
}
private void initViewModel() {
MViewModel mMViewModel = ViewModelProviders.of(this).get(MViewModel.class);
Log.i(CONSTANT.TAG_VIEW_MODEL, "ViewModelActivity_mMViewModel:" + mMViewModel.toString());
Map<String, String> map = new HashMap<>();
map.put("Java", "Java good");
map.put("Dart", "Dart good");
map.put("Kotlin", "Kotlin good");
mMViewModel.getLanguage().setValue(map);
}
}
4.在Fragment中获取MViewModel类的实例
package com.architecture.demo.viewModel;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.architecture.demo.R;
import com.architecture.demo.util.CONSTANT;
import java.util.Map;
import java.util.Set;
public class Fragment extends android.support.v4.app.Fragment implements View.OnClickListener {
private MViewModel mMViewModel;
TextView textView;
TextView textView1;
TextView textView2;
public static Fragment getInstance() {
return new Fragment();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container, false);
textView = view.findViewById(R.id.text);
textView1 = view.findViewById(R.id.text1);
textView2 = view.findViewById(R.id.text2);
textView.setOnClickListener(this);
textView1.setOnClickListener(this);
textView2.setOnClickListener(this);
initViewModel();
return view;
}
private void initViewModel() {
if (getActivity() == null) return;
mMViewModel = ViewModelProviders.of(getActivity()).get(MViewModel.class);
Log.i(CONSTANT.TAG_VIEW_MODEL, "Fragment_mMViewModel:" + mMViewModel.toString());
mMViewModel.getLanguage().observe(this, new Observer<Map<String, String>>() {
@Override
public void onChanged(@Nullable Map<String, String> map) {
if (map == null) return;
Set<Map.Entry<String, String>> entries = map.entrySet();
int i = 0;
for (Map.Entry<String, String> entry : entries) {
String key = entry.getKey();
String value = entry.getValue();
if (i == 0) {
textView.setText(key);
textView.setTag(value);
} else if (i == 1) {
textView1.setText(key);
textView1.setTag(value);
} else if (i == 2) {
textView2.setText(key);
textView2.setTag(value);
}
i++;
}
}
});
}
@Override
public void onClick(View v) {
String tag = "";
textView.setSelected(false);
textView1.setSelected(false);
textView2.setSelected(false);
if (v == textView) {
tag = (String) textView.getTag();
textView.setSelected(true);
} else if (v == textView1) {
tag = (String) textView1.getTag();
textView1.setSelected(true);
} else if (v == textView2) {
tag = (String) textView2.getTag();
textView2.setSelected(true);
}
mMViewModel.getLanguageDes().setValue(tag);
}
}
4.在Fragment2中获取MViewModel类的实例
package com.architecture.demo.viewModel;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.architecture.demo.util.CONSTANT;
import com.architecture.demo.R;
public class Fragment2 extends android.support.v4.app.Fragment {
TextView textView;
public static Fragment2 getInstance() {
return new Fragment2();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment2, container, false);
textView = view.findViewById(R.id.text);
initViewModel();
return view;
}
private void initViewModel() {
if (getActivity() == null) return;
MViewModel mMViewModel = ViewModelProviders.of(getActivity()).get(MViewModel.class);
Log.i(CONSTANT.TAG_VIEW_MODEL, "Fragment2_mMViewModel:" + mMViewModel.toString());
mMViewModel.getLanguageDes().observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String des) {
textView.setText(des);
}
});
}
}
通过以上步骤既可完成ViewModel的简单使用。
Demo地址:
https://github.com/CongYiMing/ArchitectureDemo
网友评论