【问题标题】:Hamburger icon not showing correctly after toolbar replacement更换工具栏后汉堡图标未正确显示
【发布时间】:2020-05-14 21:41:14
【问题描述】:

我有一个具有专用于工具栏的片段布局的活动。在中心,我们有一个普通的 nav_host 容器。

活动包含一个正确显示汉堡包的片段。如果我单击一个按钮,它将被第二个片段替换,该片段将旧工具栏替换为新工具栏。单击返回后,新工具栏将被旧工具栏替换。

问题是汉堡图标没有出现,工具栏也没有按预期工作。想法?

这是活动中的代码:

open fun setupToolbar() {
    initialToolbar = ToolbarFragment()
    setToolbarFragment(initialToolbar){
        setNavController()
    }
}

fun setToolbarFragment(fragment: Fragment, callback: () -> (Unit) = {}) {
    supportFragmentManager
            .beginTransaction()
            .replace(R.id.toolbarContainer, fragment)
            .runOnCommit {
                callback.invoke()
            }.commit()
}

private fun setNavController() {
    val navController = findNavController(R.id.nav_host_fragment)
    val appBarConfiguration = setFragmentsWithHamburgerMenu(navController)
    toolbar.setupWithNavController(navController, appBarConfiguration)
}

fun setFragmentsWithHamburgerMenu(navController: NavController): AppBarConfiguration {
    return AppBarConfiguration(
            setOf(
                    R.id.analyticsFragment,
                    R.id.routinesFragment,
                    R.id.currentRunFragment,
                    R.id.myMapsFragment,
                    R.id.myRobotsFragment
            ),
            drawer_layout
    )
}

这是代码而不是第二个片段:

override fun onResume() {
    super.onResume()
    val fragment = SearchToolbarFragment(searchHint, this::onQueryTextChange)
    baseActivity.setToolbarFragment(fragment) {
          // other stuff
    }

}

override fun onPause() {
    super.onPause()
    baseActivity.setupToolbar()
}

这是我的活动布局:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <variable name="viewModel" type="[package].DashboardViewModel" />
    </data>

    <androidx.drawerlayout.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">

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

            <FrameLayout
                android:id="@+id/toolbarContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_constraintTop_toTopOf="parent"/>

            <fragment
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:id="@+id/nav_host_fragment"
                android:name="androidx.navigation.fragment.NavHostFragment"
                app:defaultNavHost="true"
                app:layout_constraintBottom_toTopOf="@+id/bottom_nav"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/toolbarContainer" />

            <com.google.android.material.bottomnavigation.BottomNavigationView
                android:id="@+id/bottom_nav"
                style="@style/BottomNavigationView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/white"
                app:itemBackground="@color/white"
                app:itemTextColor="@color/button_view_item"
                app:labelVisibilityMode="labeled"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:menu="@menu/menu_bottom_nav" />

            <LinearLayout
                android:id="@+id/progressMaskLayout"
                android:layout_width="0dp"
                android:layout_height="0dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/toolbarContainer">

                <include layout="@layout/progress_mask" />
            </LinearLayout>

        </androidx.constraintlayout.widget.ConstraintLayout>

        <com.google.android.material.navigation.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:fitsSystemWindows="true">

            <include
                bind:viewModel="@{viewModel}"
                layout="@layout/element_navigation_bar"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </com.google.android.material.navigation.NavigationView>
    </androidx.drawerlayout.widget.DrawerLayout>
</layout>

【问题讨论】:

  • 您能否更具体地谈谈您遇到的问题?工具栏是否正确显示?是否显示不同的图标而不是汉堡菜单?等等……
  • 您应该发布所发生情况的屏幕截图。在我的情况下,当我将片段添加到活动时,汉堡图标动画没有完全呈现。如果我不介意,我加了一些时间来绘制完整的动画。
  • 这能回答你的问题吗:stackoverflow.com/questions/30824324/…

标签: android android-layout android-fragments android-toolbar


【解决方案1】:

为了避免这个问题,我只是在前一个片段上添加了一个片段,然后删除了添加的片段。

像这样:

fun addToolbarFragment(fragment: Fragment, callback: () -> (Unit) = {}) {
    supportFragmentManager
            .beginTransaction()
            .add(R.id.toolbarContainer, fragment)
            .runOnCommit {
                callback.invoke()
            }.commit()
}

fun removeToolbarFragment(fragment: Fragment, callback: () -> (Unit) = {}) {
    supportFragmentManager
            .beginTransaction()
            .remove(fragment)
            .runOnCommit {
                callback.invoke()
            }.commit()
}

这样,在第一个工具栏中所做的所有自定义都不会丢失。

【讨论】:

    【解决方案2】:

    首先,您使用的是 Android jetpack 导航组件,还使用片段管理器手动执行片段事务。您违背了使用喷气背包导航组件的目的。这就是使用导航库的全部意义所在,这样我们就不必手动进行片段事务了。这里你要做的就是把你的toolbar放到main_activity.xml中,这样所有的fragment都可以继承它。

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    
    <layout 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">
    
        <androidx.drawerlayout.widget.DrawerLayout
            android:id="@+id/Drawer_Main"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <androidx.coordinatorlayout.widget.CoordinatorLayout
                android:id="@+id/Layout_Coordinator_Main"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true">
    
                <com.google.android.material.appbar.MaterialToolbar
                    android:id="@+id/Toolbar_Main"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:background="?attr/colorPrimary">
    
                    <TextView
                        android:id="@+id/Toolbar_Main_Title"
                        style="@style/Locky.Text.Toolbar.TitleText"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:text="@string/app_name" />
    
                </com.google.android.material.appbar.MaterialToolbar>
    
                <androidx.core.widget.NestedScrollView
                    android:id="@+id/Nested_Scroll"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginTop="?attr/actionBarSize"
                    android:fillViewport="true">
    
                    <fragment
                        android:id="@+id/Navigation_Host"
                        android:name="androidx.navigation.fragment.NavHostFragment"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        app:defaultNavHost="true"
                        app:navGraph="@navigation/navigation_drawer_main" />
    
                </androidx.core.widget.NestedScrollView>
                <com.google.android.material.floatingactionbutton.FloatingActionButton
                    android:id="@+id/FAB_Add"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="bottom|end"
                    android:layout_margin="@dimen/fab_margin"
                    app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
                    app:srcCompat="@drawable/ic_add" />
    
            </androidx.coordinatorlayout.widget.CoordinatorLayout>
    
            <com.google.android.material.navigation.NavigationView
                android:id="@+id/Navigation_View"
                android:layout_width="280dp"
                android:layout_height="match_parent"
                android:layout_gravity="start"
                android:clipToPadding="false"
                android:paddingStart="0dp"
                android:paddingEnd="16dp"
                app:headerLayout="@layout/drawer_header"
                app:menu="@menu/menu_drawer_main" />
    
        </androidx.drawerlayout.widget.DrawerLayout>
    
    </layout>
    

    【讨论】:

    • 我已经添加了我的主要活动布局。我确实将工具栏放在我的 main_activity.xml 中。我做错了吗?
    • 我用一些代码更新了我的答案。做这样的事情,然后使用导航组件来改变你的片段。如果您需要修改工具栏的标题,只需在您的主活动中进行即可。
    猜你喜欢
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 2015-03-20
    • 2015-03-24
    • 2017-07-12
    • 1970-01-01
    相关资源
    最近更新 更多