写点什么

Android 单页应用如何在 Activity 与 Fragment 中共享状态

作者:Changing Lin
  • 2021 年 12 月 10 日
  • 本文字数:2590 字

    阅读完需:约 8 分钟

Android单页应用如何在Activity与Fragment中共享状态

1.需求

  • 设计师在设计某个单页应用时,嵌入了多个标签页,而且每个标签页的业务逻辑有较高的重复性;按照以往的开发思路是,每个 Fragment 独立自身的业务逻辑,且与其他 Fragment 无关联,甚至与父 Activity 都无过多的关联,这种方式会带来一定的缺点,比如 数据同步问题、重复冗余代码、每个 Fragment 显得很沉重等。

  • 那么有没有什么方法可以解决这个问题呢?答案是肯定的,Jetpack 库的 Lifecycle 组件。


2.知识点

  • Jetpack 是一个由多个库组成的套件,可帮助开发者遵循最佳做法、减少样板代码并编写可在各种 Android 版本和设备中一致运行的代码,让开发者可将精力集中于真正重要的编码工作。

  • Lifecycle 生命周期感知型组件可执行操作来响应另一个组件(如 Activity 和 Fragment)的生命周期状态的变化。

3.源码

  • 修改 build.gradle 来导入依赖:

dependencies {        val lifecycle_version = "2.4.0"        val arch_version = "2.1.0"
// ViewModel implementation("androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version") // LiveData implementation("androidx.lifecycle:lifecycle-livedata:$lifecycle_version") // Lifecycles only (without ViewModel or LiveData) implementation("androidx.lifecycle:lifecycle-runtime:$lifecycle_version")
// Saved state module for ViewModel implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version")
// Annotation processor annotationProcessor("androidx.lifecycle:lifecycle-compiler:$lifecycle_version") // alternately - if using Java8, use the following instead of lifecycle-compiler implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycle_version")
// optional - helpers for implementing LifecycleOwner in a Service implementation("androidx.lifecycle:lifecycle-service:$lifecycle_version")
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process implementation("androidx.lifecycle:lifecycle-process:$lifecycle_version")
// optional - ReactiveStreams support for LiveData implementation("androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version")
// optional - Test helpers for LiveData testImplementation("androidx.arch.core:core-testing:$arch_version") }
复制代码
  • 父 Activity 的不完全代码:

public class CenterActivity extends BaseActivity {
private ViewPager viewPager; private BottomNavigationView bottomNavigationView; private TextView tvTitle; private CenterViewModel viewModel; private EmptyViewModel emptyViewModel;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_pro);
bottomNavigationView = findViewById(R.id.nav_view); viewPager = findViewById(R.id.view_pager);
ViewModelProvider provider = new ViewModelProvider(this); // 基于lifecycle-viewmodel来构建,并且参数是当前Activity,父类是ComponentActivity emptyViewModel = provider.get(EmptyViewModel.class); // 构建EmptyViewModel对象 viewModel = provider.get(CenterViewModel.class); // 构建CenterViewModel对象 viewPager.setAdapter(viewModel.getAdapter(this)); viewPager.addOnPageChangeListener(onPageChangeListener);
bottomNavigationView.setOnNavigationItemSelectedListener(this::onNavigationItemSelected); }}
复制代码
  • 子 Fragment 的不完全代码:

public class DashboardFragment extends Fragment {
private DashboardViewModel dashboardViewModel; private FragmentDashboardBinding binding; private MapView mMapView = null; private MapViewModel mapViewModel; private Bundle savedInstanceState; private EmptyViewModel emptyViewModel; private HomeViewModel homeViewModel;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ViewModelProvider provider = new ViewModelProvider(getActivity()); // 基于lifecycle-viewmodel来构建,并且参数是父Activity,即上面的CenterActivity dashboardViewModel = provider.get(DashboardViewModel.class);
binding = FragmentDashboardBinding.inflate(inflater, container, false); View root = binding.getRoot();
final TextView textView = binding.textDashboard; mMapView = binding.map; mapViewModel = provider.get(MapViewModel.class); this.savedInstanceState = savedInstanceState;
permissionConfigMap();
binding.ibCenter.setOnClickListener(this::onClick);
emptyViewModel = provider.get(EmptyViewModel.class); // 构建EmptyViewModel对象,请注意 此时的emptyViewModel对象与CenterActivity中的emptyViewModel是同一个对象 homeViewModel = provider.get(HomeViewModel.class);
binding.positionTitleView.setAdapter(emptyViewModel.getAdapter((BaseActivity) getActivity()));
return root; }}
复制代码

4.验证

  • 通过添加日志打印,我们可以在日志窗口看到如下,至此 Activity 与 Fragment 中共享状态问题得到解决,我们可以把 状态存放到 ViewModel 中,便于访问。

2021-12-10 17:27:11.723 25482-25482/com.nufront.app_master E/cclin: [, , 0]:这里是CenterActivity:name.EmptyViewModel@2353d44a2021-12-10 17:27:12.158 25482-25482/com.nufront.app_master E/cclin: [, , 0]:这里是DashboardFragment页面:name.EmptyViewModel@2353d44a
复制代码


发布于: 4 小时前阅读数: 7
用户头像

Changing Lin

关注

获得机遇的手段远超于固有常规之上~ 2020.04.29 加入

我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。

评论

发布
暂无评论
Android单页应用如何在Activity与Fragment中共享状态