^(코딩캣)^ = @"코딩"하는 고양이;

[단편 Android 개발 정리] 사이드 메뉴(DrawerLayout) 구현하기 (2021년 버전)

API/Android
2021. 7. 8. 21:22

단편 Android 개발 정리

이전 게시글: ActionBar 대신 Toolbar로 대체하기(2021년 버전)

 

사이드 메뉴(DrawerLayout) 구현하기 (2021년 버전)

이전 게시글에서 ActionBar를 Toolbar로 대체한 다음 햄버거 버튼까지 추가해 보았다. 본 게시글에서는 햄버거 버튼을 클릭하면 사이드 메뉴가 나타나는 것까지 구현해 보겠다. 안드로이드에서는 햄버거 버튼을 클릭했을 때 측면에서 스르륵 나타나는 사이드 메뉴를 DrawerLayout이라고 부른다. 이전 게시글의 레이아웃에서 이를 덧붙여보겠다.

이전 게시글에서 햄버거 버튼까지 반영했을 때의 레이아웃은 다음과 같다.

<?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"
    tools:context=".MainActivity">
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:menu="@menu/menu_toolbar">
    </androidx.appcompat.widget.Toolbar>
</androidx.constraintlayout.widget.ConstraintLayout>

그리고 액티비티에 대한 코틀린 클래스는 다음과 같다. import는 생략한다.

class MainActivity : AppCompatActivity() {
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(R.layout.activity_main)

		val toolbar = findViewById<Toolbar>(R.id.toolbar)
		setSupportActionBar(toolbar)

		supportActionBar?.setDisplayHomeAsUpEnabled(true)
		supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_menu)
	}

	override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    	// ...
		return super.onCreateOptionsMenu(menu)
	}

	override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
    	// ...
		return super.onPrepareOptionsMenu(menu)
	}

	override fun onOptionsItemSelected(item: MenuItem): Boolean {
		var result = false

		when (item.itemId) {
        	// ...
		}

		return result;
	}
}

ConstraintLayout을 기준으로 설명하면, 맨 위에 Toolbar가 있고 그 아래에 붙여서 DrawerLayout을 배치할 것이다. 그러면 레이아웃은 다음과 같이 작성할 수 있다.

<androidx.constraintlayout.widget.ConstraintLayout ...>
	<androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" ...>
	</androidx.appcompat.widget.Toolbar>
	<androidx.drawerlayout.widget.DrawerLayout
        android:id="@+id/layout_drawer"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/toolbar"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="이 곳은 메인 영역이다." />
        <com.google.android.material.navigation.NavigationView
            android:id="@+id/navigation_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:fitsSystemWindows="true">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="이 곳은 사이드 영역이다." />
        </com.google.android.material.navigation.NavigationView>
    </androidx.drawerlayout.widget.DrawerLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

TextView는 영역 사이의 구분을 명확히 하기 위하여 임의로 넣은 요소이다. 아무튼 레이아웃을 저렇게 작성한다. DrawerLayout 내부에 사이드 메뉴가 보여질 NavigationView가 있다는 것이다. 특히 주목할 것은 NavigationView가 갖는 android:layout_gravity="start" 속성이다. 이 속성은 사이드 메뉴가 왼쪽에서 나타났다가 왼쪽으로 사라짐을 의미한다. 오른쪽 사이드 메뉴는 android:layout_gravity="end"로 하면 된다.

그 다음 이전 포스트에서 햄버거 메뉴를 클릭할 때 호출되는 이벤트는 다음과 같이 처리한다. 사이드 메뉴가 이미 떠 있다면(isDrawerOpen) 그것을 감추고(closeDrawer), 사이드 메뉴가 감춰져 있다면 그것을 드러낸다(openDrawer).

class MainActivity : AppCompatActivity() {
	override fun onOptionsItemSelected(item: MenuItem): Boolean {
		var result = false

		when (item.itemId) {
			android.R.id.home -> {
				val layoutDrawer = findViewById<DrawerLayout>(R.id.layout_drawer)
				val gravity = GravityCompat.START

				if (layoutDrawer.isDrawerOpen(gravity)) {
					layoutDrawer.closeDrawer(gravity)
				} else {
					layoutDrawer.openDrawer(gravity)
				}
			}
		}

		return result;
	}
}

실행 결과는 다음과 같다.

햄버거 버튼을 누르기 전
햄버거 버튼을 누른 후

디자인적 요소는 최대한 배제한 채, 최소한 접고 펼치는 기능적인 구현은 이것으로 끝.

 

카테고리 “API/Android”
more...