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

Posted

技术标签:

【中文标题】片段和导航抽屉的不同工具栏【英文标题】:Different toolbar for fragments and Navigation Drawer 【发布时间】:2016-05-03 02:17:16 【问题描述】:

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

【问题讨论】:

【参考方案1】:

不确定我的方法是否好,但我尝试将此公共方法添加到我的活动中:

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();

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

【讨论】:

我解决了这个问题。只是我在活动布局中使用DrawerLayout,在片段布局中使用Toolbar,在onCreateView 中设置Toolbar,如ActionBar 并将其与DrawerLayout 同步。 而且您的解决方案没有任何内存泄漏) @Шах 您想详细说明您是如何与片段onCreateView 中的DrawerLayout 同步的吗?您是否为每个片段Toolbar 重新创建ActionBarDrawerToggle?您是否使用 DrawerLayout 构造函数,有或没有 Toolbar @Шах,是的,请回答,您是如何获得具有不同工具栏的应用程序的? А то у меня выглядят ужасно. @ CoolMind,Простовофрагменте,гдетыопределилсвойToolbarвonCreateViewустановиегокакActionBarисинхронизируйсDrawerLayoutтакже,каквобычнойактивити。 对于英语,我不记得如何需要在onCreateView 中定义Toolbar 才能像ActionBarDrawerLayout 一样使用。【参考方案2】:

您可以从每个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();

【讨论】:

你能描述一个活动和片段吗?所有片段都有自己的工具栏还是使用活动?我有一个带有 DrawerLayout 和 NavigationView 的活动,其中放置了片段,它们包含 CoordinatorLayout、AppBarLayout、工具栏,但效果不佳,更改片段时工具栏看起来不像我想要的那样。【参考方案3】:

如果您想在不同的片段中使用您在导航抽屉中指定的appbar(toolbar),例如不同的选项菜单项,您可以在指定导航抽屉逻辑的主活动中创建一个公共方法。

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,它与您在主活动中用于主工具栏的 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);

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

【讨论】:

不,不,伙计,这不是问题。我需要为不同的片段制作一个非常灵活和复杂的 GUI。它需要对 appbar 的完全访问权限 只是我有带有视差标题、导航路径(如在某些文件管理器中)等的片段。【参考方案4】:

我也有同样的问题。我只想在主片段中添加 CollapsingToolbar。通过从 Activity 中删除工具栏,我丢失了汉堡包按钮和与drawerLayout 的连接。为了解决这个问题,我没有删除activity中的Toolbar,并使其透明。对于每个片段,我创建了自己的自定义工具栏。最后,我有一个链接到 Drawer 的汉堡按钮和一个运行良好的 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_
    android:layout_
    tools:context=".activity.MainActivity">

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_
    android:layout_>

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar"
        android:layout_
        android:layout_
        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_
            android:layout_
            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);

这适用于具有 sdk 版本 21 的 Android。

【讨论】:

【参考方案5】:

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

【讨论】:

这是唯一的解决方案吗?我需要重新附加几乎所有视图层次结构 您必须了解您正在尝试更改主体视图而不是父视图,因为 AppBarLayout 仍然嵌入在 DrawerLayout 主体中。所以最好的做法是重新声明布局。如果所有片段的 NavigationView 都相同,则可以将其编写在单独的 xml 布局文件中并使用 可以缩短代码。 好的,谢谢!只是我认为这个解决方案在片段切换上可能需要很多时间。但我会用它。

以上是关于片段和导航抽屉的不同工具栏的主要内容,如果未能解决你的问题,请参考以下文章

带有片段的 Android Studio 导航抽屉。工具栏隐藏在下一个片段活动或页面中

导航抽屉的片段管理

Android如何使用工具栏中的按钮切换以使用片段打开/关闭导航抽屉

导航抽屉和工具栏出现在初始屏幕中

如何删除导航抽屉?

导航抽屉没有覆盖我的工具栏[重复]