从片段更改工具栏

Change toolbar from fragment

我正在使用 jetpack recommended architecture, NavigationUI, and the navigation graph 编写应用程序。所以我有一个主 activity 和一个 Toolbar、一个 BottomNavigationViewNavHostFragment.

到目前为止一切正常:我需要更改 Toolbar 以使用 CollapsingToolbarLayout 并将 BottomNavigationView 隐藏在我的一个片段中。

我尝试添加一个导航侦听器(如 here 所述)以隐藏我的 ToolbarBottomNavigationView,并且在我的片段中,我膨胀了新的 Toolbar并在 activity.

上调用 setSupportActionBar()
// in MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
  // ...
  navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
        if(destination.getId() == R.id.detailFragment){
          bottomBar.setVisibility(View.GONE);
          topBar.setVisibility(View.GONE);
        }else{
          bottomBar.setVisibility(View.VISIBLE);
          topBar.setVisibility(View.VISIBLE);
        }
      });
  // ...
}

public void changeToolbar(Toolbar toolbar){
  getSupportActionBar().hide();
  setSupportActionBar(toolbar);
}

// in DetailFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
  Bundle savedInstanceState) {
  // ...
  navController = NavHostFragment.findNavController(this);

  AppBarConfiguration.Builder builder = new Builder(
      R.id.accuracyFragment,
      R.id.dataFragment,
      R.id.magnetFragment,
      R.id.settingsFragment);
  AppBarConfiguration config = builder.build();
  NavigationUI.setupWithNavController(toolbarLayout, toolbar, navController);
  ((MainActivity)getActivity()).changeToolbar(toolbar);
  // ...
}

它几乎可以正常工作,但是:

  1. 当我向上导航或转​​到另一个片段时,BottomNavigationView 未正确显示。好像被Toolbar.
  2. 压下去了
  3. 过渡很丑陋:工具栏正在明显变化,我可以看到它在变化之前就消失了

所以问题是:是否有另一种方法 change/hide 来自片段的导航元素?如果没有,我应该创建一个新的 activity 吗?

这是一次疯狂的旅程,但我终于找到了解决办法。对于问题编号 1,这是由于 Android 管理 fitsSystemWindows 属性 传播的方式所致。为了使其正常工作,我对布局进行了一些更改。我创建了一个自定义 FitSystemWindowLinearLayout,它只是一个 class 扩展标准 LinearLayout 并覆盖 onApplyWindowInsets,如下所示:

  @Override
  public WindowInsets onApplyWindowInsets(WindowInsets insets) {
    int childCount = getChildCount();
    for (int index = 0; index < childCount; ++index) {
      getChildAt(index).dispatchApplyWindowInsets(insets);
    }

    return insets;
  }

我的主要 activity 现在看起来像这样:

+-- CoordinatorLayout, fitsSystemWindows=false
    +-- FitSystemWindowLinearLayout, fitsSystemWindows="false"
        +-- Toolbar
        +-- NavHostFragment, fitsSystemWindows="false"
        +-- BottomNavigationView, fitsSystemWindows="false"

对于第二个问题,即过渡丑陋,我通过向过渡添加共享元素来缓解这个问题。

总而言之,我认为使用新的 activity 更容易处理此类事情,NavigationUI 现在有点不足。

以下是一些对我有帮助的资源: