android-fragments - 导航抽屉:如何在切换(不旋转)时使片段持久(保持活动状态)
问题描述
片段不会在Fragment:setRetainInstance(true);
手机方向更改时重新实例化。当然,我希望我的片段在从一个片段切换到另一个片段时保持活力。但是 Android Studio 4 提供了一个向导模板,只有
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
从数小时的调试和搜索网络中,如果认为它需要从类中固有,FragmentNavigator
所以我可以覆盖FragmentNavigator:naviagte
创建新片段的位置 final Fragment frag = instantiateFragment(..
,然后添加, ft.replace(mContainerId, frag);
所以我可以找到我的旧片段并使用ftNew.show
andftOld.hide
代替。当然这是一个愚蠢的想法,因为这种navigate
方法充满了其他内部的东西。
而且我不知道它FrameNavigator
是在哪里创建的。我可以在MainActivity:OnCreate
with中检索它
NavigatorProvider navProvider = navController.getNavigatorProvider ();
Navigator<NavDestination> navigator = navProvider.getNavigator("fragment");
但当时我只能用我的派生版本替换它。而且没有replaceNavigtor
方法,只有addNavigator
方法,在哪里调用?
无论如何,这一切都将非常复杂,因此容易出错。 为什么没有简单的选项可以让我的片段保持活力:-(
在较旧的向导模板中,有可能
@Override
public void onNavigationDrawerItemSelected(int position) {
Fragment fragment;
switch (position) {
case 1:
fragment = fragment1;
break;
case 2:
fragment = fragment2;
break;
case 3:
fragment = fragment3;
break;
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if(mCurrentFragment == null) {
ft.add(R.id.container, fragment).commit();
mCurrentFragment = fragment;
} else if(fragment.isAdded()) {
ft.hide(mCurrentFragment).show(fragment).commit();
} else {
ft.hide(mCurrentFragment).add(R.id.container, fragment).commit();
}
mCurrentFragment = fragment;
}
但我不知道如何使用我的 MainActivity 仅派生为的 Android 4.0 模板执行此操作:
public class MainActivity extends AppCompatActivity {
private AppBarConfiguration mAppBarConfiguration;
欢迎提出想法:'(
解决方案
您好,抱歉我迟到的回答!我在导航抽屉和导航组件方面遇到了类似的问题。我尝试了一下,找到了一个可行的解决方案,这可能对其他人也有帮助。
关键是MainActivity的FragmentManager中自定义FragmentFactory的使用。请参阅下面的代码:
公共类 StaticFragmentFactory 扩展 FragmentFactory { 私人 myNavHostFragment1 行程NavHostFragment; 私人 myNavHostFragment2 设置NavHostFragment; @NonNull @Override 公共片段实例化(@NonNull 类加载器类加载器,@NonNull 字符串类名){ if (MyNavHostFragment1.class.getName().equals(className)) { 如果(this.myNavHostFragment1 == null){ this.myNavHostFragment1 = new MyNavHostFragment1(); } 返回 this.myNavHostFragment1 ; } else if (MyNavHostFragment2.class.getName().equals(className)) { 如果(this.myNavHostFragment2 == null){ this.myNavHostFragment2 = new MyNavHostFragment2(); } 返回 this.myNavHostFragment2; } return super.instantiate(classLoader, className); } }
FragmentFactory 使用 AndroidX 的 NavigationComponent 在不同片段之间的导航中幸存下来。为了使片段保持活动状态,FragmentFactory 存储应该存在的片段实例,如果它不为空,则返回此实例。在类中使用单例模式时,您可以找到类似的模式。
您必须通过调用在相应的活动中注册 FragmentFactory
this.getSupportFragmentManager().setFragmentFactory(new StaticFragmentFactory())
另请注意,我在这里使用嵌套片段,因此一个顶级片段(此处称为 NavHostFragmen)包含多个子片段。所有片段都使用其父片段的相同 FragmentFactory。上面的自定义 FragmentFactory 返回超类方法的结果,当要实例化的 Fragment 不知道是否保持活动状态时。
推荐阅读
- machine-learning - PCANET中的线性层(卷积层)
- pandas - 在多列 DataFrame 上获取日志值
- php - 如何在 Symfony 4 中实现处理程序?
- javascript - 使用 SQL 数据库中的 PHP 和 JavaScript 登录
- git - 如何修复文件`package.json`中命令`git flow`的操作?
- html - CSS 过渡适用于 IE,但不适用于 Firefox、Chrome 和 Opera
- java - 如何将值的键传递给HashMap中的变量
- javascript - AJAX 延迟下一行的执行
- c# - 如何获取附近攻击的数据以避免?
- java - 无法解决 FirebaseOptions.Builder().setCredentials()