핀수로그
  • [Android] Bottom Appbar와 FloatingActionButton (feat. Appbar left margin 없애기)
    2022년 12월 01일 14시 06분 36초에 업로드 된 글입니다.
    작성자: 핀수
    728x90
    반응형

    제작일지

    벌써 붙잡고 있은지 일년이 넘어가는 내 아픈 손가락...

    날씨 앱..이다지도 골치 아픈것이었단 말인가

    날씨날씨 앱 만드신 분들 정말 존경합니다..너무 잘쓰고 있어요..(갑자기 분위기 영상편지

    쉬게 된 김에 반드시 제대로 만들어 출시시키겠다는 목표를 가지고 다시 키보드를 잡았다.

    아 개발자가 화면 구성하려니 머리가 다 뽑히는 것 같은데 사실상 이것 때문에 일년 가까이 시간 잡아 먹었다는게 학계의 정설

    (해당 카테고리 이전 글을 읽으면 모두 알 수 있는....)

    디자인 하시는 분들도 정말..정말 존경합니다.

    각설하고

    필자는 이런식으로 앱 구성을 하길 원했다.

    출처 : (좌) https://dribbble.com/shots/16015884-The-Space-mobile-app-design / (우) 마이케이티 앱

    후자 쪽이 내가 더 원하던 느낌이었는데

    이건 바텀 네비게이션은 아닌 것 같고… 도대체 뭘까 하며 뒤져보다

    우연히 바텀 앱바와 플로팅 액션 버튼의 조합임을 알게 되었다.

    BottomAppbar 알아보기

    Material Design 문서에 있는 사용 방법이다.

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        ...
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <!-- Note: A RecyclerView can also be used -->
        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingBottom="100dp"
            android:clipToPadding="false">
    
            <!-- Scrollable content -->
    
        </androidx.core.widget.NestedScrollView>
    
        <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bottomAppBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            style="@style/Widget.MaterialComponents.BottomAppBar.Colored"
            app:navigationIcon="@drawable/ic_menu_24dp"
            app:menu="@menu/bottom_app_bar"
            />
    
        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:srcCompat="@drawable/ic_add_24dp"
            app:layout_anchor="@id/bottomAppBar"
            />
    
    </androidx.coordinatorlayout.widget.CoordinatorLayout>

    중요하게 눈여겨 볼 점은 CoordinatorLayout 과 FloatingActionButton의 layout_anchor 속성이다.

    나머지는 보통의 앱바 사용법과 다르지 않아보이므로..넘어가겠다.

    CoordinatorLayout

    공식문서에 따르면 CoordinatorLayout은 강력한 FrameLayout이라고 설명하고 있다.

    여러 속성을 중첩해 사용하고 그에 따른 상호작용을 원활하게 도와줄 수 있는 레이아웃으로 이해하면 좋을 것 같다.

    (문서에 사용된 단어들로는 이해하기 쉽지 않다..)

    일전에 플로팅 액션 버튼을 누르면 해당 버튼이 커지면서

    어떤 창으로 전환되는 애니메이션 효과를 적용한 적이 있는데 그때 사용된 것도 CoordinatorLayout 이었다.

    다른 레이아웃을 바로 위 부모로 두니 원하는대로 동작하지 않더라.

    layout_anchor

    플로팅 액션 버튼에 있던 속성이다.

    이 속성을 지워버리면 플로팅 액션 버튼은 엄한데 가있는다.

    anchor는 우리 말로하면 ‘닻’이다.

    어디다 정착시킬 건지? 정도로 이해했다. 그래서 앱바로 지정해주니 원하는 레이아웃이 나왔다.

    BottomAppbar 사용하기

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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"
        android:orientation="vertical"
        tools:context=".view.MainActivity">
    
    
        my contents..
    
        <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:id="@+id/main_appbar_root"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_gravity="bottom"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/main_nav_host"
            app:layout_constraintVertical_weight="1.1">
    
            <com.google.android.material.bottomappbar.BottomAppBar
                android:id="@+id/main_appbar"
                style="@style/Widget.MaterialComponents.BottomAppBar.Colored"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:layout_gravity="bottom"
                app:contentInsetStart="0dp"
                tools:ignore="BottomAppBar">
    
                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">
    
                    <ImageView
                        android:id="@+id/main_home_iv"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:src="@drawable/ic_main"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintEnd_toStartOf="@+id/main_bookmark_iv"
                        app:layout_constraintHorizontal_bias="0.5"
                        app:layout_constraintHorizontal_weight="5"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent" />
    
                    <ImageView
                        android:id="@+id/main_bookmark_iv"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:src="@drawable/ic_my_page"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintHorizontal_bias="0.5"
                        app:layout_constraintHorizontal_weight="5"
                        app:layout_constraintStart_toEndOf="@+id/main_home_iv"
                        app:layout_constraintTop_toTopOf="parent" />
                </androidx.constraintlayout.widget.ConstraintLayout>
    
            </com.google.android.material.bottomappbar.BottomAppBar>
    
            <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/main_add_location_fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_anchor="@id/main_appbar"
                app:srcCompat="@drawable/ic_add" />
        </androidx.coordinatorlayout.widget.CoordinatorLayout>
    
    
    </androidx.constraintlayout.widget.ConstraintLayout>

    뭐가 이렇게 길어! 싶겠지만 한번 살펴보도록 하자.

    기존 공식문서와 내것이 다른 이유는 일반적인 바텀네비게이션처럼 아이콘이 배치되었기 때문이다.

    앱바를 커스텀하려면 안에 레이아웃을 두면 되는데 그 과정에 ConstraintLayout이 추가 되었다.

    Appbar left margin 없애기

    앱바를 적용해본 분들은 알겠지만 자동으로 영역이 잡히는 것을 알 수 있다.

    app:navigationIcon 속성을 통해 앱바 아이콘을 설정하면 아래와 같다.

     

    이때는 app:contentInsetStart 속성을 0dp로 주면 된다.


    References

    아래 글을 참고하여 작성 되었습니다.

    https://developer.android.com/reference/androidx/coordinatorlayout/widget/CoordinatorLayout

    https://m2.material.io/components/app-bars-bottom/android#bottom-app-bar

    728x90
    반응형
    댓글