在 Fragment 之间共享数据
同一个Activity下的多个Fragment之间实现数据共享:
1.ViewModle中的共享数据用MutableLiveData<T> 定义。
2.使用ViewModelProvider持有相同Activity并生成ViewModle实例。
Activity:
public class ThirdActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
}
}
activity_third:1,2一组。3,4一组
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".TimerActivity">
<fragment
android:id="@+id/fragmnetone"
android:name="com.ycq.jetpack.OneFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<View
android:layout_width="match_parent"
android:layout_height="10dp"/>
<fragment
android:id="@+id/fragmnettwo"
android:name="com.ycq.jetpack.TwoFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<View
android:layout_width="match_parent"
android:layout_height="10dp"/>
<fragment
android:id="@+id/fragmnetthird"
android:name="com.ycq.jetpack.ThirdFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<View
android:layout_width="match_parent"
android:layout_height="10dp"/>
<fragment
android:id="@+id/fragmnetfour"
android:name="com.ycq.jetpack.FourFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
使用LiveData+ViewModle实现
ShareDataViewModel :
public class ShareDataViewModel extends ViewModel {
private MutableLiveData<Integer> progress;
public MutableLiveData<Integer> getProgress() {
if (progress == null) {
progress = new MutableLiveData<>();
}
return progress;
}
@Override
protected void onCleared() {
super.onCleared();
progress = null;
}
}
OneFragment:
liveData观察到数据发生变化,将值赋给seekBar
public class OneFragment extends Fragment {
public OneFragment() {
}
private MutableLiveData<Integer> liveData;
private SeekBar seekbar;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one, container, false);
ShareDataViewModel viewModel = ViewModelProviders.of(getActivity()).get(ShareDataViewModel.class);
liveData = viewModel.getProgress();
seekbar = view.findViewById(R.id.seekbar);
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
liveData.setValue(i);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
liveData.observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer progress) {
seekbar.setProgress(progress);
}
});
return view;
}
}
fragment_one:与fragment_two相同
<?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"
android:layout_gravity="center"
tools:context=".OneFragment">
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
TwoFragment :
public class TwoFragment extends Fragment {
public TwoFragment() {
}
private MutableLiveData<Integer> liveData;
private SeekBar seekbar;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_two, container, false);
ShareDataViewModel viewModel = ViewModelProviders.of(getActivity()).get(ShareDataViewModel.class);
liveData = viewModel.getProgress();
seekbar = view.findViewById(R.id.seekbar);
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
liveData.setValue(progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
liveData.observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer progress) {
seekbar.setProgress(progress);
}
});
return view;
}
}
使用LiveData+ViewModle+DataBinding的形式
TFViewModel :
public class TFViewModel extends ViewModel {
private MutableLiveData<String> progress;
public MutableLiveData<String> getProgress() {
if (progress == null) {
progress = new MutableLiveData<>();
}
return progress;
}
public void setProgress(String progressStr) {
if (progress == null) {
progress = new MutableLiveData<>();
}
progress.setValue(progressStr);
}
@Override
protected void onCleared() {
super.onCleared();
progress = null;
}
}
ThirdFragment :
public class ThirdFragment extends Fragment {
public ThirdFragment() {
}
private TFViewModel viewModel;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FragmentThirdBinding binding = FragmentThirdBinding.inflate(inflater, container, false);
binding.setLifecycleOwner(this);
viewModel = ViewModelProviders.of(getActivity()).get(TFViewModel.class);
binding.setData(viewModel);
binding.btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i("11111", "ThirdFragment:" + viewModel.getProgress());
}
});
return binding.getRoot();
}
}
布局文件相同,采用双向数据绑定的形式
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="data"
type="com.ycq.jetpack.TFViewModel"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="center">
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:hint="输入内容"
android:text="@={data.progress}"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:text="点击"
android:layout_height="wrap_content"/>
</LinearLayout>
</layout>
FourFragment :
public class FourFragment extends Fragment {
public FourFragment() {
}
private TFViewModel viewModel;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FragmentFourBinding binding = FragmentFourBinding.inflate(inflater, container, false);
binding.setLifecycleOwner(this);
viewModel = ViewModelProviders.of(getActivity()).get(TFViewModel.class);
binding.setData(viewModel);
binding.btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i("11111", "FourFragment:" + viewModel.getProgress().getValue());
}
});
return binding.getRoot();
}
2020/07/30 14:34