1. 关于ViewModel和LiveData
关于ViewModel和LiveData,谷歌Android开发文档介绍的比较详细:
ViewModel 概览
下面是我自己的例子,实现两个Fragment直接数据共享,拖动其中一个SeekBar,另一个跟着变化。
2. 示例效果
3. 创建ViewModel类
public class MyViewModel extends ViewModel {
private MutableLiveData<Integer> mProgress;
public MutableLiveData<Integer> getProgress(){
if (mProgress == null){
mProgress = new MutableLiveData<>();
mProgress.setValue(0);
}
return mProgress;
}
}
4. 新建两个Fragment
两个Fragment分别是FirstFragment
、SecondFragment
。两个Fragment创建完成后,自动生成了fragment_first.xml
、fragment_second.xml
,代码分别为:
fragment_first.xml
:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FirstFragment">
<!-- TODO: Update blank fragment layout -->
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:min="0"
android:max="100"/>
</FrameLayout>
fragment_second.xml
:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondFragment">
<!-- TODO: Update blank fragment layout -->
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:min="0"
android:max="100"/>
</FrameLayout>
FirstFragment.java
:
public class FirstFragment extends Fragment {
private View mRootView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mRootView == null){
mRootView = inflater.inflate(R.layout.fragment_first, container, false);
SeekBar seekBar = mRootView.findViewById(R.id.seekbar);
MyViewModel myViewModel = new ViewModelProvider(getActivity(), new ViewModelProvider.AndroidViewModelFactory(getActivity().getApplication()))
.get(MyViewModel.class);
myViewModel.getProgress().observe(getActivity(), new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
seekBar.setProgress(integer);
}
});
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
myViewModel.getProgress().setValue(i);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
return mRootView;
}
}
SecondFragment.java
:
public class SecondFragment extends Fragment {
private View mRootView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mRootView == null){
mRootView = inflater.inflate(R.layout.fragment_second, container, false);
SeekBar seekBar = mRootView.findViewById(R.id.seekbar);
MyViewModel myViewModel = new ViewModelProvider(getActivity(), new ViewModelProvider.AndroidViewModelFactory(getActivity().getApplication()))
.get(MyViewModel.class);
myViewModel.getProgress().observe(getActivity(), new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
seekBar.setProgress(integer);
}
});
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
myViewModel.getProgress().setValue(i);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
return mRootView;
}
}
5. Fragment添加到MainActivity中
activity_main.xml
:
<?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=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/firstFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:name="com.example.viewmodelexample.FirstFragment"/>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/secondFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:name="com.example.viewmodelexample.SecondFragment"/>
</LinearLayout>
6. 示例代码
https://gitee.com/jie-xio/android_samples/tree/master/ViewModel/ViewModelExample