[Android/Custom] NavigationView Custom하기
Android/Custom

[Android/Custom] NavigationView Custom하기


📌 Android NavigationView Custom

 

일반적인 NavigationView와는 완전히 다른 모양새의 NavigationView를 만들어야할 때가 있다.

 

이런 것이라 든지..

NavigationView는 기본적으로 구현되어 있는 header과 menu inflate를 통해 구현할 수 있지만 그와 같은  방법으로는 원하는 대로 변경하기는 어렵다.

 

따라서 이 글에서는 NavigationView 전체를 내 입맛대로 변경시키기 위한 방법을 알아보도록 하겠다.

 

📗 구현

 

우선 NavigationView도 중요하지만 NavigationView 위에 DrawerLayout을 설정해줄 필요가 있다.

Drawer = 서랍, 한마디로 서랍 레이아웃인데, NavigationView의 open close 상태 및 상호작용을 알아서 다 해주기 때문에 이를 사용하면 매우 편리하다. 

 

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

    <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".view.MainActivity">

            ... 

    </androidx.constraintlayout.widget.ConstraintLayout>

    <include layout="@layout/main_navi"
             app:layout_constraintLeft_toLeftOf="parent"
             app:layout_constraintTop_toTopOf="parent"
             app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.drawerlayout.widget.DrawerLayout>

Hot Ez Ex) fitsSystemWindows 옵션을 true로 설정할 시 NavigationView가 toolbar 부분을 덮고 Open된다.

Hot Ez Ex) DrawerLayout은 자식 레이아웃으로 반드시 2개만을 가진다. 아니라면 Error을 내뿜는다

 

include 위의 ConstraintLayout은 옆에서 튀어나올 NavigationView를 제외한 메인이 화면을 구성하는 Layout이다.

NavigationView에도 많은 코드가 들어갈 수 있으므로 include 태그를 통해 다른 레이아웃으로 뺀다.

 

 

//XML (main_navi.xml)
<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"
        android:background="@drawable/background_navigation"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">

    <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/nav_layout"
            android:layout_width="270dp"
            android:layout_height="match_parent">
            
            ... 기존 레이아웃 짜듯이 작성 ...

    </androidx.constraintlayout.widget.ConstraintLayout>

</com.google.android.material.navigation.NavigationView>

위에서 include한 main_navi.xml의 형태이다. 

사실 이 부분이 NavigationView의 Custom에 있어서 전부라고 해도 무방하다.

<NavigationView> 내부에 ViewGroup을 설정하여 자신의 입맛대로 수정하면 된다.

 

이제 Activity 내에서 처리해줄 것만 구현하면 된다.

 

// in View
override fun onBackPressed() {
    if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
        drawer_layout.closeDrawer(GravityCompat.START)
    } else {
        super.onBackPressed()
    }
}

뒤로가기 키 눌렀을 때의 Drawer닫기 행동이다. 

사실 이거 말고도 필요한 것은 하나 더 있다. 바로 NavigationView를 여는 버튼의 행동 설정이다.

이는 아래 옵션이면 해결된다.


drawer_layout.openDrawer(GravityCompat.START) // trigger되면 NavigationView Open

drawer_layout.closeDrawer(GravityCompat.START) // trigger되면 NavigationView Close

 

이 함수를 적당한 버튼에 Click Event로 설정해주자.

 

 

📘 Include로 Layout을 나누었을 때의 Data binding 방법

 

Layout XML 코드에서 몇 줄을 추가해준다.

 

// databinding layout
<layout
	...
    xmlns:bind="http://schemas.android.com/apk/res-auto">

    <include layout="@layout/main_navi"
         app:layout_constraintLeft_toLeftOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintBottom_toBottomOf="parent"
         bind:viewModel="@{viewModel}"/>

 </layout>

bind:받는곳에서받을이름="@{보낼변수}" 이런 식으로 바인딩 객체값을 넘겨주면 된다.

 

그럼 객체값을 받는 곳에서는 어떻게 해야할까?

 

<layout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <import type="android.view.View"/>
        <variable name="viewModel"
                  type="xxxx.MainViewModel"/>
    </data>
    
</layout>

<variable name="받는곳에서받을이름" type"~"/>

 

이런 식으로 받은 객체값을 처리해주면 된다. 

'Android > Custom' 카테고리의 다른 글

[Android/Custom] BottomNavigationView Icon 변경하기  (0) 2019.11.14
Android Bottom Navigation Custom하기  (0) 2019.08.20