Как реализовать новый материал BottomAppBar как BottomNavigationView

Я пытался реализовать новый BottomAppBar, который обычно выглядит следующим образом: материал BottomAppBar как BottomNavigationView, как в домашнем приложении Google, которое выглядит следующим образом.

Моя проблема в том, что, поскольку я могу заполнить BottomAppBar только ресурсом меню, я не могу понять, как выровнять мои кнопки, чтобы они выглядели как BottomNavigationView (но с "вырезанным" для кнопки Fab) вместо того, чтобы выровнять все по одной стороне BottomAppBar.

Как я могу добавить собственный макет внутри этого нового Material BottomAppBar?

Или вместо этого, есть ли способ реализовать BottomNavigationView с "cut" для кнопки Fab (сохраняя при этом классные анимации по умолчанию, такие как новый BottomAppBar)?

3 ответа

Решение

РЕШИТЬ

По сути, вместо того, чтобы пытаться принудительно настроить ресурсы меню в нужном мне макете, я использовал это решение, а просто поместил LinearLayout внутри BottomAppBar, используя "пустой" элемент, как предложил @dglozano.

С помощью ?attr/selectableItemBackgroundBorderless Я также могу добиться эффекта, который действительно похож на BottomNavigationView.

<com.google.android.material.bottomappbar.BottomAppBar
    android:id="@+id/bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:gravity="center"
    app:layout_anchorGravity="start"
    app:hideOnScroll="true"
    app:fabAnimationMode="scale"
    app:fabAlignmentMode="center"
    app:backgroundTint="@color/colorPrimary">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="5"
        android:paddingEnd="16dp">
        <ImageButton
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:srcCompat="@drawable/ic_home_white_24dp"
            android:background="?attr/selectableItemBackgroundBorderless"
            android:tint="@color/secondary_text"/>
        <ImageButton
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:srcCompat="@drawable/ic_map_black_24dp"
            android:background="?attr/selectableItemBackgroundBorderless"/>
        <ImageButton
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@android:color/transparent"/>
        <ImageButton
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:srcCompat="@drawable/ic_people_white_24dp"
            android:background="?attr/selectableItemBackgroundBorderless"/>
        <ImageButton
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:srcCompat="@drawable/ic_account_circle_24dp"
            android:background="?attr/selectableItemBackgroundBorderless"/>
    </LinearLayout>
</com.google.android.material.bottomappbar.BottomAppBar>

Поместите bottomAppBar под bottomNavigationView с прозрачным фоном. И добавьте пустой пункт меню в menu.xml, чтобы освободить место для FAB.

XML:

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/lt_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:fitsSystemWindows="false">


<ViewPager
    android:id="@+id/main_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="56dp"
    android:layout_above="@+id/bottom_navigation"
    android:layout_alignParentStart="true" />


<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:labelVisibilityMode="labeled"
    android:layout_gravity="bottom"
    android:layout_alignParentBottom="true"
    android:background="@color/transparent"
    app:menu="@menu/bottom_menu" />

<com.google.android.material.bottomappbar.BottomAppBar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/bottom_bar"
    android:layout_gravity="bottom"/>

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_anchor="@id/bottom_bar"/>

Результат

Команда, реализующая материальные компоненты для Android, говорит, что этот дизайн не является частью спецификации, но они щедро предлагают простое решение, которое можно увидеть по ссылке ниже.

Можно ли иметь BottomAppBar и FloatingActionButton с равномерным распределением меню? #72

По сути, нужно изменить параметры макета контейнера кнопок меню:

if(bottomAppBar.childCount > 0) {
     val actionMenuView = bottomAppBar.getChildAt(0) as androidx.appcompat.widget.ActionMenuView
     actionMenuView.layoutParams.width = androidx.appcompat.widget.ActionMenuView.LayoutParams.MATCH_PARENT   
}

Комбинация этого с вашим пунктом меню void поможет избежать использования другого компонента Android.

1 - Включите Maven в свой репозиторий в build.gradle

allprojects {
    repositories {
        jcenter()
        maven {
            url "https://maven.google.com"
        }
    }
}

2 - Поместите зависимость компонентов материала в свой build.gradle. Имейте в виду, что версия материала регулярно обновляется.

implementation 'com.google.android.material:material:1.0.0-alpha1'

3 - Установите для compileSdkVersion и targetSdkVersion последнюю версию API для Android P, которая равна 28.

4 - убедитесь, что ваше приложение наследует Theme.MaterialComponents тема для того, чтобы сделать BottomAppBar использовать последний стиль. В качестве альтернативы вы можете объявить стиль для BottomAppBar в объявлении виджета в файле макета XML следующим образом.

style=”@style/Widget.MaterialComponents.BottomAppBar”

5 - Вы можете включить BottomAppBar в свой макет следующим образом. BottomAppBar должен быть дочерним по отношению к CoordinatorLayout.

<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottom_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="@color/colorPrimary"
app:fabAlignmentMode="center"
app:fabAttached="true"
app:navigationIcon="@drawable/baseline_menu_white_24"/>

6 - Вы можете привязать кнопку с плавающим действием (FAB) к BottomAppBar, указав идентификатор BottomAppBar в атрибуте app:layout_anchor FAB. BottomAppBar может удерживать FAB на заднем плане или FAB может перекрывать BottomAppBar.

<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/baseline_add_white_24"
app:layout_anchor="@id/bottom_app_bar" />

7. Существует множество атрибутов, которые можно использовать для настройки нижней навигационной панели и значка Fab.

8 - Проверьте этот средний пост для более полного объяснения.


ОБНОВЛЕНИЕ: проверьте ответ OP для окончательного решения для его конкретной проблемы.

Это может помочь кому-то достичь вышеуказанного дизайна. Добавьте пустой пункт меню, чтобы настроить кнопку fab и пробел.

<androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/gray"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">


     <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bottom_bar"
            style="@style/AppTheme.BottomAppBar"
            android:layout_width="match_parent"
            android:layout_height="?android:attr/actionBarSize"
            android:layout_gravity="bottom"
            android:backgroundTint="@color/bottom_bar">

        <com.google.android.material.bottomnavigation.BottomNavigationView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/transparent"
                app:itemIconTint="@color/white"
                app:labelVisibilityMode="unlabeled"
                app:menu="@menu/bottom_menu">

        </com.google.android.material.bottomnavigation.BottomNavigationView>
    </com.google.android.material.bottomappbar.BottomAppBar>


    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:backgroundTint="@color/bottom_bar"
            android:src="@drawable/ic_plus"
            android:visibility="visible"
            app:borderWidth="0dp"
            app:fabAlignmentMode="end"
            app:fabCradleMargin="20dp"
            app:fabSize="normal"
            app:layout_anchor="@id/bottom_bar"
            app:maxImageSize="38dp"
            app:tint="@color/white">

    </com.google.android.material.floatingactionbutton.FloatingActionButton>

Это должно сработать для вас

Результат

        <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingTop="?attr/actionBarSize">
    
        <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bottom_bar"
            style="@style/Widget.MaterialComponents.BottomAppBar"
            android:layout_width="match_parent"
            android:layout_gravity="bottom"
            android:layout_height="wrap_content" >
    
            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
    
                <com.google.android.material.bottomnavigation.BottomNavigationView
                    android:id="@+id/nav_view"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_gravity="center_horizontal"
                    android:layout_margin="0dp"
                    android:background="@drawable/transparent"
                    android:padding="0dp"
                    app:menu="@menu/bottom_nav_menu" />
            </FrameLayout>
    
    
        </com.google.android.material.bottomappbar.BottomAppBar>
    
        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchor="@id/bottom_bar"/>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>