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

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

【问题讨论】:

    标签: android android-fragments android-toolbar navigation-drawer


    【解决方案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_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);
    

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

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