본문 바로가기
깡샘 코틀린

11-6 드로어 레이아웃 - 옆에서 열리는 화면 구성

by 농농씨 2023. 6. 29.

드로어 레이아웃(DrawerLayout)은 액티비티 화면에 보이지 않던 내용이 왼쪽이나 오른쪽에서 손가락의 움직임에 따라 밀려나오는 기능을 한다. androidx의 라이브러리인 드로어 레이아웃은 마치 서랍(drawer)처럼 열리는 메뉴를 구성할 때 사용한다.

ex. 카카오맵(지금은 업뎃돼서 바뀌었나?) 화면 왼쪽을 탭해서 오른쪽으로 밀면 목록으로 구현된 화면이 나온다.

 

더보기

(개정판 삭제)

드로어 레이아웃을 사용하려면 그래들 파일의 dependencies 항목에 다음처럼 선언해야 한다.

// 드로어 레이아웃 선언
implementation 'androidx.drawerlayout:drawerlayout:1.1.1'

드로어 레이아웃을 액티비티에 적용하려면 액티비티의 레이아웃 XML 파일 구성이 중요하다. 레이아웃 XML 파일에서 드로어 메뉴가 출력되어야 하는 부분의 태그를 DrawerLayout으로 선언한다. 액티비티 레이아웃 XML 파일의 루트 태그가 꼭 Drawerlayout일 필요는 없다. 하지만 대부분은 액티비티의 기본 화면이 보이고 그 위를 덮듯이 나오게 하므로 액티비티 레이아웃 XML 파일의 루트 태그를 DrawerLayout으로 선언한다. 그리고 Drawerlayout 아래에는 뷰를 2개 선언해야 한다. 이렇게 선언만 해주면 자동으로 첫번째 하위 태그 부분을 액티비티 화면에 출력하고 두 번째 하위 태그 부분이 안 보이다가 끌려 나온다.(??)

// 드로어 레이아웃 구성
<androidx.drawerlayout.widget.DrawerLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout ...생략...> // 첫 번째 하위 태그
    </LinearLayout>
    <TextView // 두 번째 하위 태그
    	android:layout_gravity="start" />
</androidx.drawerLayout.widget.DrawerLayout>

최상위에는 <androidx.drawerlayout.widget.DrawerLayout> 태그를, 그 아래에는 <LinearLayout>과 <TextView> 태그를 선언했다. 하위 태그는 어떤 태그여도 상관없다. 태그가 2개여야 하는 것이 중요하다.(!!) 이렇게 XML 설정만 해도 첫 번째 태그에 해당하는 화면이 알아서 나오고 사용자가 화면 끝을 밀면 두 번째 태그에 해당하는 화면이 나타난다.

두 번째 태그의 android:layout_gravity 속성값을 이용하여 화면에서 나오는 방향을 지정할 수도 있다. 즉, left, right, start를 지정하고 start값은 사용하는 언어의 방향에 따라 left, right가 자동으로 결정된다(한국어는 왼쪽).

 

레이아웃 XML만으로 드로어 레이아웃을 이용할 수 있는데, 대부분 툴바 영역에 토글(toggle) 버튼(≡)(왼쪽 위에 작대기 세개 메뉴버튼느낌)을 함께 제공한다.

드로어 메뉴 토글 버튼은 ActionBarDrawerToggle 클래스에서 제공한다.

// 드로어 메뉴 토글 버튼 적용
class DrawerActivity : AppCompatActivity() {
	lateinit var toggle: ActionBarDrawerToggle
    override fun onCreate(savedinstanceState: Bundle?) {
    	(...생략...)
        // ActionBarDrawerToggle 버튼 적용
        toggle = ActionBarDrawerToggle(this, binding.drawer, R.string.drawer_opened,
        	R.string.drawer_closed)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        toggle.syncState()
    }
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
    	// 이벤트가 토글 버튼에서 발생하면
        if (toggle.onOptionsItemSelected(item)) {
        	return true
        }
        return super.onOptionsItemSelected(item)
    }
}

ActionBarDrawerToggle 생성자의 두 번째 매개변수는 토글 버튼으로 여닫는 드로어 객체이다. 그리고 세 번째와 네 번째 매개변수는 문자열 리소스로, 드로어가 열리거나 닫혔을 때의 상태를 표현한 문자열이다.

supportActionBar?.setDisplayHomeAsUpEnabled(true) 구문은 토글 버튼으로 사용할 아이콘이 출력되게 한다. 그런데 원래 액션바 영역의 HomeAsUp 아이콘은 왼쪽 화살표(←) 모양이다. 만약 (왼쪽화살표 대신에) 드로어를 열기 위해 제공하는 내비게이션 아이콘(≡)이 나오게 하려면 toggle.syncState() 함수까지 설정해 줘야 한다. 이렇게 하면 드로어가 출력되기 전에는 내비게이션 아이콘이 나오다가 출력되면 왼쪽 화살표 아이콘으로 바뀐다.(내비게이션 아이콘으로 바꾸기 내용)

그런데 여기까지 설정하면 화면에 토글 버튼이 잘 보이기는 하지만 버튼을 클릭했을 때 드로어가 열리지 않는다. 왜냐하면 토글 버튼도 액션바 영역에 나오는 아이콘이므로 내부에서 메뉴로 취급하기 때문이다. 따라서 메뉴 이벤트를 처리하는 함수인 onOptionItemSelected()에서 토글 버튼의 이벤트를 처리해 줘야 한다. 그래야지만 토글 버튼으로 드로어를 제어할 수 있다.(내비게이션 아이콘 실행 내용) 이와 관련한 코드는 실습파트에서~