-
[Android Kotlin] Navigation Drawer를 이용한 사이드 메뉴 만들기개발 끄적끄적/Android 2020. 6. 1. 20:48반응형
Google Play Store, Gmail 등 많은 앱에서 사용되고 있는 메뉴를 알아보겠습니다. 三 모양의 버튼(일명 햄버거 버튼)으로 왼쪽에서 열리는 사이드 메뉴를 많이 보셨을텐데요. 직접 커스텀할 수 있는 사이드 메뉴를 만들어보겠습니다.
DrawerLayout
서랍이라는 의미의 Drawer를 따서 DrawerLayout은 '평소에는 숨어 있다가 사용자의 액션을 받아 나타나는 기능을 도와주는 레이아웃' 입니다. DrawerLayout 자체가 사라지는 것이 아닌 DrawerLayout에 추가된 child layout이 서랍의 기능을 하도록 해주는 것입니다.
하지만 DrawerLayout의 모든 child layout이 서랍의 기능을 수행하는 것은 아닙니다.
보통 DrawerLayout의 자식은 두개의 layout으로 구성됩니다.
하나는 메뉴(서랍)가 열리기 전 화면을 보여주는 activity이며,
다른 하나는 메뉴의 화면을 담당하는 fragment입니다.
xml의 가장 최상단은 DrawerLayout으로 구성됩니다. 자식으로 fragment와 activity를 가지며,
fragment에 layout_gravity 값을 주어 메뉴로써 동작하게 합니다.layout_gravity에 "left" 값을 주면 왼쪽에서 열리고 닫히는 메뉴가 되며, 반대로 "right" 값을 주면 오른쪽에서 열리고 닫히는 메뉴가 됩니다.
메뉴는 기본적으로 끝을 스와이프(Edge Swipe)해 열 수 있습니다.
그 외에 동적으로 열고 닫기 위해서는 openDrawer() 메소드와 closeDrawer() 메소드가 사용됩니다.본 포스팅에서는 버튼 하나에 openDrawer() 메소드를 달아 사용해보겠습니다.
아래는 파라미터에 따른 openDrawer() 메소드입니다.
리턴 타입 함수 설명 void openDrawer(drawerView : View,
animate : Boolean)drawerView 열기. animate에 따라 애니메이션 결정.
(API 24.0.0 이상)void openDrawer(drawerView : View) 애니메이션과 함께 drawerView 열기 void openDrawer(gravity : Int) 지정된 Drawer를 gravity 방향에서 애니메이션과 함께 열기 void openDrawer(gravity : Int, animate Boolean) 지정된 Drawer를 gravity 방향에서 열기. animate에 따라 애니메이션 여부 결정 (API 24.0.0 이상) Drawer가 swipe 에 의해 열리고 닫히는 것을 막기 위한 메소드도 있습니다.
setDrawerLockMode(lockMode : Int) 입니다.
lockMode 값 설명 LOCK_MODE_UNLOCKED 0x00000000 Lock 기능 비활성화. Swipe에 의해 열리고 닫힘 LOCK_MODE_LOCKED_CLOSED 0x00000001 Drawer가 닫힌 채로 잠김. 만약 Drawer가 열려있었다면 닫힘 LOCK_MODE_LOCKED_OPEN 0x00000002 Drawer가 열린 채로 잠김. 만약 Drawer가 닫혀있었다면 열림 이 메소드는 swipe에 의한 열림/닫힘을 막아주는 기능만 있어서 openDrawer()와 closeDrawer() 메소드에 의한 열림/닫힘은 여전히 동작합니다.
open_menu_btn 이라는 버튼에 메뉴 열기 기능을 주고 DrawerLayout 안의 버튼, layout에 기능을 부여하는 예제를 만들어보았습니다. MainActivity.kt 의 setContentView가 activity_main 이 아닌 main_include_drawer인 점을 유의해주시길 바랍니다.
우선 액션바를 따로 사용하지 않을 것이기에 theme를 AppTheme.NoActionBar로 설정해줍니다.
1. res - values - styles 에 아래와 같은 스타일을 만들어줍니다.
2. manifest의 application에 theme를 변경해줍니다.
이제 MainActivity와 연결할 DrawerLayout을 생성해줍니다.
main_include_drawer.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/main_drawer_layout" tools:openDrawer="start" android:fitsSystemWindows="true" android:layout_width="match_parent" android:layout_height="match_parent"> <!--fitsSystemWindows를 true로 지정할 경우 뷰가 차지할 수 있는 영역을 소프트키, 상태바를 제외한 영역까지 넓혀줍니다.--> <include android:layout_width="match_parent" android:layout_height="match_parent" layout="@layout/activity_main"/> <com.google.android.material.navigation.NavigationView android:id="@+id/navigation_view" android:orientation="vertical" android:background="#313131" android:layout_gravity = "left" app:itemTextColor="#fff" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <include android:id="@+id/main_header_include_logged_in" android:visibility="invisible" app:layout_constraintTop_toTopOf="parent" android:layout_width="match_parent" android:layout_height="wrap_content" layout="@layout/main_drawer_header_logged_in"/> <include android:id="@+id/main_header_include_logged_out" android:visibility="visible" app:layout_constraintTop_toTopOf="parent" android:layout_width="match_parent" android:layout_height="wrap_content" layout="@layout/main_drawer_header_logged_out"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@id/main_header_include_logged_in" app:layout_constraintLeft_toLeftOf="parent" android:orientation="vertical"> <Button android:id="@+id/main_navigation_btn1" android:clickable="true" android:enabled="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#313131" style="?android:attr/borderlessButtonStyle" android:layout_marginLeft="21dp" android:layout_marginTop="20dp" android:text="메뉴 1" android:textSize="18sp" android:textColor="#777777"/> <Button android:id="@+id/main_navigation_btn2" android:clickable="true" android:enabled="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#313131" style="?android:attr/borderlessButtonStyle" android:layout_marginLeft="21dp" android:text="메뉴 2" android:textSize="18sp" android:textColor="#777777"/> <Button android:id="@+id/main_navigation_btn3" android:clickable="true" android:enabled="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#313131" style="?android:attr/borderlessButtonStyle" android:layout_marginLeft="21dp" android:text="메뉴 3" android:textSize="18sp" android:textColor="#777777"/> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout> </com.google.android.material.navigation.NavigationView> </androidx.drawerlayout.widget.DrawerLayout>
MainActivity.kt
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_include_drawer) //버튼을 눌러 메뉴를 오픈할 수도 있고, 왼쪽에서 오른쪽으로 스왑해 오픈할 수 있습니다. //DrawerLayout의 id에 직접 openDrawer()메소드를 사용할 수 있습니다. open_menu_btn.setOnClickListener { main_drawer_layout.openDrawer((GravityCompat.START)) } navigation_header_logout_btn.setOnClickListener { logOut() } navigation_header_login_btn.setOnClickListener { logIn() } main_navigation_btn1.setOnClickListener { //버튼1 클릭 시 } main_navigation_btn2.setOnClickListener { //버튼2 클릭 시 } main_navigation_btn3.setOnClickListener { //버튼3 클릭 시 } } private fun logOut(){ main_header_include_logged_in.visibility = View.INVISIBLE main_header_include_logged_out.visibility = View.VISIBLE main_navigation_btn1.isEnabled = false main_navigation_btn1.setTextColor(Color.parseColor("#777777")) main_navigation_btn2.isEnabled = false main_navigation_btn2.setTextColor(Color.parseColor("#777777")) main_navigation_btn3.isEnabled = false main_navigation_btn3.setTextColor(Color.parseColor("#777777")) } private fun logIn(){ main_header_include_logged_in.visibility = View.VISIBLE main_header_include_logged_out.visibility = View.INVISIBLE main_navigation_btn1.isEnabled = true main_navigation_btn1.setTextColor(Color.parseColor("#ffffff")) main_navigation_btn2.isEnabled = true main_navigation_btn2.setTextColor(Color.parseColor("#ffffff")) main_navigation_btn3.isEnabled = true main_navigation_btn3.setTextColor(Color.parseColor("#ffffff")) } }
실행화면
반응형'개발 끄적끄적 > Android' 카테고리의 다른 글
[Android Kotlin] 갤러리에서 이미지 가져와 RecyclerView에 적용하기 (0) 2020.06.03 [Android Kotlin] Permission(권한) 얻기 (0) 2020.06.02 [Android Kotlin] RecyclerView Adapter View Type (리사이클러뷰 여러 뷰타입) (0) 2020.06.01 [Android Studio] 초보 개발자 로그캣(LogCat) 확인 방법 - 에러 찾는 방법 (0) 2020.05.30 [JAVA] 오라클 JDBC 연결, insert문 실행해보기 (0) 2020.05.30