【问题标题】:Sync Navigation Drawer menu on Back stack后堆栈上的同步导航抽屉菜单
【发布时间】:2014-04-02 16:58:27
【问题描述】:

我遵循https://github.com/jamesmontemagno/Xam.NavDrawer 示例,我能够成功地使用带有片段的抽屉布局(实际上是带有视图寻呼机的嵌套片段)。我有一个问题,当我单击后退按钮时,左侧的导航抽屉菜单项未与显示的片段同步。

这就是我导航到其他片段的方式

 SupportFragmentManager.BeginTransaction().Replace(Resource.Id.content, fragment).AddToBackStack(fragment.Name).Commit();

我尝试了 OnAttachFragment 方法,但它没有在返回堆栈上调用。我也尝试了 SupportFragmentManager BackStackChanged 方法,但我无法获取视图中的当前片段来更新导航抽屉菜单标题。

【问题讨论】:

    标签: c# android xamarin xamarin.android navigation-drawer


    【解决方案1】:

    我遇到了同样的问题,也找不到任何解决方案。虽然这个问题有点老了,但我的解决方案可能会对某人有所帮助。我不确定这是否是最好的解决方案,但它对我有用。

    所以首先你需要添加变量来存储之前检查过的项目的ID:

    private int previousItemChecked;
    

    最初将其设置为您的默认选中项:

    if (savedInstanceState == null) {
        selectItem(0);
        previousItemChecked = 0;
    }
    

    然后编辑片段事务,使 backstack 中的事务标题包含转换为字符串的先前检查项目的位置,并在事务完成后将变量 previousItemChecked 设置为当前检查的项目 ID:

    fragmentManager.beginTransaction().replace(R.id.content_frame, selectedFragment).addToBackStack(""+previousItemChecked).commit();
    previousItemChecked = mDrawerList.getCheckedItemPosition();
    

    最后在onBackPressed方法中,你需要获取之前分配给fragment transaction的字符串,将其解析为int并根据获得的id更新drawer:

    @Override
    public void onBackPressed() {
        if(fragmentManager.getBackStackEntryCount() > 0) {
            String title = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount()-1).getName();
            int pos = Integer.parseInt(title);
            previousItemChecked = pos;
            mDrawerList.setItemChecked(pos, true);
        }
        super.onBackPressed();
    }
    

    我从我在 Android Studio 中创建的应用程序中获取了代码,因此它不适用于 Xamarin,但如果您更新代码,它也应该可以使用它。这里重要的是它是如何完成的。我希望答案是可以理解的,并且会对某人有所帮助。

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,我是这样解决的:

      在 selectItem 中,我们传递了位置 Item; 因此,如果位置为 0(或者我们希望它首先出现在菜单上的位置的任何片段),我们必须避免保存第一个事务。所以……

      private void selectItem(position){
      
          //...
      
          if (position != 0)
          {
              SupportFragmentManager.BeginTransaction()
                  .Replace(Resource.Id.content_frame, fragment)
                  .AddToBackStack(fragment.Name)
                  .Commit();
          }
          else
          {
              SupportFragmentManager.BeginTransaction()
                  .Replace(Resource.Id.content_frame, fragment)
                  .Commit();
          }
      }
      

      【讨论】:

        【解决方案3】:

        通过将DestinationChangedListener 注入NavController 来实现这一点,如下所示:

        NavController navController.addOnDestinationChangedListener(this);
        

        然后:

        @Override
        public void onDestinationChanged(@NonNull NavController controller,
                                         @NonNull NavDestination destination,
                                         @Nullable Bundle arguments) {
            NavigationView navigationView = findViewById(R.id.nav_view);
            if(navigationView != null){
                navigationView.setCheckedItem(destination.getId());
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-11-03
          • 1970-01-01
          • 2022-06-30
          • 1970-01-01
          • 1970-01-01
          • 2018-12-09
          • 2018-03-26
          • 1970-01-01
          相关资源
          最近更新 更多