片段和导航抽屉的不同工具栏

Different toolbar for fragments and Navigation Drawer

请向我解释一下...我的 Activity 中有导航抽屉,它与 Toolbar 同步(如 ActionBar)。 Activity 有几个片段,在不同的片段中我需要使用不同的 AppBar 模式(一个视差,另一个简单)。所以,我认为我应该在每个带有 AppBar 和内容的框架中设置 CoordinatorLayout
但是我如何替换新工具栏上的最后一个工具栏以保存与抽屉的同步?还是方法不对,我需要改成其他方法?

如果您将 DrawerLayoutNavigationView 用于导航抽屉,根据我的最佳解决方案是为每个片段布局使用单独的 DrawerLayout 并使用 AppBarLayoutDrawerLayout 的正文中,每个片段都不同。

不确定我的方法是否好,但我尝试将此 public 方法添加到我的 activity:

public void setToolbar(Toolbar toolbar) {
    if(toolbar != null) {
        setSupportActionBar(toolbar);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();
    } else {
        drawer.setDrawerListener(null);
    }
}

我在所有片段中添加了这个:

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    ((MainActivity)getActivity()).setToolbar(toolbar);
}

@Override
public void onDestroyView() {
    ((MainActivity)getActivity()).setToolbar(null);
    super.onDestroyView();
}

它工作正常,但我不确定它是否会导致内存泄漏或任何其他性能问题。也许有人可以帮忙?

您可以从每个 Fragment 访问主 DrawerLayout,就像下面的代码一样:

AppCompatActivity actionBar = (AppCompatActivity) getActivity();
actionBar.setSupportActionBar(toolbar);

DrawerLayout drawer = (DrawerLayout) actionBar.findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            getActivity(), drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();

如果你想在不同的片段中使用你在导航抽屉中指定的 appbar(toolbar),例如不同的选项菜单项,你可以在 Main Activity 中创建一个 public 方法您指定导航抽屉逻辑的位置。

public void setToolbar(Toolbar toolbar, String title){
    AppCompatActivity actionBar = this;
    actionBar.setSupportActionBar(toolbar);

    DrawerLayout drawer = (DrawerLayout)actionBar.findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toogle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close);
    drawer.addDrawerListener(toogle);
    toogle.setDrawerIndicatorEnabled(true);
    toogle.syncState();
    if(toolbar != null)
        toolbar.setTitle(title);
}


现在你可以在你的片段中使用这个方法来访问主工具栏并用你的自定义标题,选项菜单覆盖它...... 您可以通过在您的片段中创建一个新的工具栏变量然后在 onCreateView() 方法中膨胀它来做到这一点

toolbarFragment = (Toolbar)getActivity().findViewById(R.id.toolbar);

R.id.toolbar 是您在布局文件中指定的工具栏的 ID,它与您在主 activity 中使用的 ID 相同对于主工具栏。


现在你可以像这样

在片段中调用方法setToolbar(Toolbar toolbar, String title)
((MainActivity)getActivity()).setToolbar(toolbarFragment, "Some title");


如果你想为这个片段使用选项菜单,你必须调用

setHasOptionsMenu(true);

在片段 onCreate()onCreateView() 方法中。之后你可以像这样覆盖方法onCreateOptionsMenu()

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.custom_menu1, menu);
}

您也可以对导航抽屉中的其他片段重复此过程。虽然对我有用,但我不知道这是否违反了活动或碎片生命周期或导致内存韭菜。

我也遇到了同样的问题。我只想在主要片段中添加 CollapsingToolbar。通过从 Activity 中删除工具栏,我失去了汉堡包按钮和与 drawerLayout 的连接。为了解决这个问题,我没有把activity里面的Toolbar删掉,改成了透明的。对于每个片段,我都创建了自己的自定义工具栏。最后,我有一个链接到抽屉的汉堡包按钮和一个 well-functioning CollapsingToolbar。我知道那是拐杖。但是我找不到别的方法

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.MainActivity">

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:theme="@style/AppTheme.AppBarOverlay"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </com.google.android.material.appbar.AppBarLayout>

    <include
        android:id="@+id/include"
        layout="@layout/content_main"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

为了让 AppBar 完全不可见,我添加了

AppBarLayout appBarLayout = findViewById(R.id.appbar);
appBarLayout.setOutlineProvider(null);

这适用于 Android SDK 版本 21。