【问题标题】:Back navigation with Fragments / Toolbar带有片段/工具栏的返回导航
【发布时间】:2015-03-08 18:53:07
【问题描述】:

我现在正在为这个挠头......我有一个ActionBarActivity,它加载了一个初始Fragment - 原始菜单在活动中膨胀。 Now, I have a navigation bar that, when an item is selected, loads a different fragment and adds this to the backstack.

当我这样做时,我想设置几件事:

  1. 将家设置为向上指示器
  2. 使主活动中的选项菜单无效
  3. Set 的 Fragment 选项为 true
  4. 确保向上指示器正确导航回原始片段

发生了一些相当奇怪的事情 - 向上指示器只出现一次,并且不像后退按钮,虽然我已经使新菜单无效并膨胀,但新菜单会附加到原始活动菜单。

编辑:好的,我已经解决了附加问题 - 忘记在 onCreateOptionsMenu 方法中添加 menu.clear()

我的导航抽屉布局对所有菜单项都有onClick 方法,这会触发另一个片段的加载:

public void navItemClick(View view) {

        switch (view.getId()) {
            case R.id.ripSMS:
                mNavigationDrawer.toggleHome(false);
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                FragmentTransaction mTrans = getSupportFragmentManager().beginTransaction();
                mTrans.replace(R.id.voiceover_frame_layout,new MessageFragment(),"main_ui")
                        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).addToBackStack("msg").commit();
                break;
            case R.id.ripEmail:
                break;
            case R.id.ripSettings:
                break;
        }

        mNavigationDrawer.closeDrawer();
    }

切换主页:

public void toggleHome(boolean show) {
        mDrawerToggle.setDrawerIndicatorEnabled(show);

        if (!show) {
            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        } else {
            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
        }
    }

一旦项目被触发,onCreate 将包含无效和 hasOptions 代码:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getActivity().invalidateOptionsMenu();
    setHasOptionsMenu(true);
}

onCreateOptionsMenu 然后扩展另一个菜单布局(包含一个称为设置的项目)。

如前所述,这仅部分有效 - 第一次使用该项目加载 Fragment 时,我得到了后退图标,但它也不起作用(这是在 onOptionsItemSelected 中设置的以检查主页项目按下 -它什么都不做)。当我按下后退按钮时,它会将我带回正确的位置。但是,如果我向后导航,即使代码通过onCreate 运行,后退箭头现在也会显示更长的时间!

【问题讨论】:

    标签: android fragment android-toolbar android-actionbaractivity fragment-backstack


    【解决方案1】:

    好的,经过反复试验,我设法解决了这个问题。进行了两项更改:

    1. 实施addOnBackStackChangedListener
    2. ActionBarDrawerToggle's setToolbarNavigationClickListener 需要设置

    由于我只有一个活动(其他都是 Fragment 类),因此我将 backstack 侦听器添加到父活动的 onCreate 方法中:

    getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
            @Override
            public void onBackStackChanged() {
                if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
                    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                } else {
                    getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                }
            }
        });
    

    这解决了返回片段时消失的返回箭头。最后将监听器添加到我的 NavigationDrawer 的设置类中:

    mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    getActivity().onBackPressed();
                }
            });
    

    我想我唯一的问题是所有指向使用 onOptionsItemSelected 方法和 android.R.id.home 但这对我没有用。当然,这可能是我实现事物的方式,但如果有人看到任何明显的原因,请告诉我!

    【讨论】:

      【解决方案2】:

      这些步骤可帮助您在加载片段时在工具栏中显示返回按钮。并在点击时弹出。

      在您的活动中将setNavigationOnClickListener 设置为工具栏。

      final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
          toggle = new ActionBarDrawerToggle(
                  this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
          drawer.setDrawerListener(toggle);
          toggle.syncState();
      
          toolbar.setNavigationOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                if(getSupportFragmentManager().getBackStackEntryCount() > 0){
                    getSupportFragmentManager().popBackStack();
                }else {
                    drawer.openDrawer(GravityCompat.START);
                }
              }
          });
      

      在您的活动中实现FragmentManager.OnBackStackChangedListener。并在OnCreate()SupportFragmentManager注册它

       getSupportFragmentManager().addOnBackStackChangedListener(this);
      

      OnBackStackChangedListener实现方法:

      @Override
      public void onBackStackChanged() {
          if(getSupportFragmentManager().getBackStackEntryCount() > 0){
              getSupportActionBar().setDisplayHomeAsUpEnabled(true);
          }else {
              getSupportActionBar().setDisplayHomeAsUpEnabled(false);
              toggle.syncState();
          }
      }
      

      【讨论】:

      • 这是经过大量斗争后唯一对我有用的解决方案。感谢分享!调用toggle.syncState(); 是一个关键因素,否则汉堡菜单在您返回后将不可见。
      【解决方案3】:

      对我来说,上面的答案还不够,但我使用了@Hamz4h_ 并在深入了解 ActionBarDrawerToggle 类后添加了更多内容。我只是从活动的 onCreate 中调用我的这个方法:

      private void initNavigationElements() {
          final ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                  this, mBinding.drawerLayout, mBinding.appBarMain.toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
          mBinding.drawerLayout.addDrawerListener(toggle);
      
          // Tricking the toggle by giving it its own arrow as a custom indicator. 
          // It will use it when setDrawerIndicatorEnabled is called with false
          toggle.setHomeAsUpIndicator(toggle.getDrawerArrowDrawable());
          toggle.syncState();
      
          getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
              @Override
              public void onBackStackChanged() {
                  DrawerArrowDrawable drawerArrowDrawable = toggle.getDrawerArrowDrawable();
                  if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
                      // 1 - Display as arrow
                      drawerArrowDrawable.setProgress(1);
                      toggle.setDrawerIndicatorEnabled(false);
      
                  } else {
                      // 2 - Display as arrow menu
                      drawerArrowDrawable.setProgress(0);
                      toggle.setDrawerIndicatorEnabled(true);
                  }
              }
          });
      
          toggle.setToolbarNavigationClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  // This is called only when setDrawerIndicatorEnabled is set as false, meaning we are not at the "root" fragment.
                  getSupportFragmentManager().popBackStackImmediate();
              }
          });
      }
      

      希望这会对某人有所帮助:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-22
        相关资源
        最近更新 更多