안드로이드 개발자의 창고
[42일차 Android] DrawerLayout 본문
출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 PPT
📖 DrawerLayout
- 좌측 상단의 네비게이션 버튼을 누르면 좌측에서 메뉴가 나타나는 UI
- 대부분이 구현되어 있으므로 필요한 부분만 변경해서 사용한다.
- 새로운 Activity를 추가할 때 Navigation Drawer Activity를 선택한다.
구조
activity_main.xml
- <include>
- 다른 layout을 포함시키는 요소
- 프래그먼트가 교체되는 화면 부분에 해당하며 layout/app_bar_main.xml 파일이 설정되어 있다.
- nav_view(NavigationView)
- 좌측에서 나타나는 메뉴가 나타날 수 있도록 해주는 View
- headerLayout에는 nav_header_main.xml을, menu에는 menu/activity_main_drawer.xml을 이용하여 구성되어 있다.
- nav_header_main.xml : 좌측에서 나타나는 NavigationView의 상단 부분
- menu/activity_main_drawer.xml : NavigationView의 하단 부분, 메뉴 파일을 이용해 사용자가 선택할 화면 목록을 구성한다.
app_bar_main.xml
- toolbar
- 화면의 toolbar에 관련된 설정을 할 수 있다.
- <include>
- layout/content_main.xml 파일이 설정되어 있다.
-
이 부분에는 fragment가 존재하며 이 fragment 에 다른 Fragment를 표시하여 화면을 교체하는 역할을 하게 된다.
content_main.xml
- nav_host_fragment
-
보여주고자 하는 Fragment들을 설정하는 부분
-
navGraph 속성에 보여줄 Fragment들이 등록되어 있는 xml 파일을 설정한다.
-
navigation/mobile_navigation.xml
- Controller가 관리할 Fragment들을 등록하는 xml 파일
- 이 파일에 Fragment를 등록할 때 설정하는 id가 매우 중요하다.
- 좌측에서 나타나는 메뉴를 클릭했을 때 클릭한 메뉴의 id와 동일한 id가 셋팅되어 있는 fragment가 화면에 나타나게 된다.
- 이 부분은 모두 설정되어 있기 때문에 개발자는 Fragment를 등록할 때 id를 메뉴의 id와 동일하게만 설정해주면 된다.
예제 코드
nav_header_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/nav_header_height"
android:background="@drawable/side_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="@+id/imageViewHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/nav_header_desc"
android:paddingTop="@dimen/nav_header_vertical_spacing"
app:srcCompat="@mipmap/ic_launcher_round" />
<TextView
android:id="@+id/textViewHeader1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:text="@string/nav_header_title"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
<TextView
android:id="@+id/textViewHeader2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nav_header_subtitle" />
</LinearLayout>
- 이 부분은 로그인한 사용자와 관련된 정보를 여주는 부분이다.
- 보통 로그인한 사용자에 따라 표시되는 데이터가 다르기 때문에 코드로 처리해주는 것이 일반적이다.
values/strings.xml
<resources>
...
<string name="first_name">First</string>
<string name="second_name">Second</string>
<string name="third_name">Third</string>
</resources>
- 각 프래그먼트의 이름으로 사용할 문자열을 등록한다.
navigation/mobile_navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/mobile_navigation"
app:startDestination="@id/firstFragment">
<fragment
android:id="@+id/firstFragment"
android:name="com.test.android64_drawlayout.ui.FirstFragment"
android:label="@string/first_name"
tools:layout="@layout/fragment_first" />
<fragment
android:id="@+id/secondFragment"
android:name="com.test.android64_drawlayout.SecondFragment"
android:label="@string/second_name"
tools:layout="@layout/fragment_second" />
<fragment
android:id="@+id/thirdFragment"
android:name="com.test.android64_drawlayout.ThirdFragment"
android:label="@string/third_name"
tools:layout="@layout/fragment_third" />
</navigation>
- 사용할 프래그먼트들을 설정해준다.
menu/activity_main_drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="@+id/firstFragment"
android:icon="@android:drawable/ic_menu_compass"
android:title="첫번째 프래그먼트" />
<item
android:id="@+id/secondFragment"
android:icon="@android:drawable/ic_menu_directions"
android:title="두번째 프래그먼트" />
<item
android:id="@+id/thirdFragment"
android:icon="@android:drawable/ic_menu_delete"
android:title="세번째 프래그먼트" />
</group>
</menu>
- 메뉴를 등록한다.
- 메뉴 항목의 id는 mobile_navigation.xml에 등록한 프래그먼트들의 id와 일치해야 한다.
- 사용자가 선택한 메뉴의 id와 동일한 id로 등록되어 있는 프래그먼트가 나타난다.
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.appBarMain.toolbar)
// Step01 ============================================
// Header 부분의 LinearLayout을 추출한다.
val headerLayout = binding.navView.getHeaderView(0) as LinearLayout
// 하위의 View들을 추출한다.
val navHeaderMainBinding = NavHeaderMainBinding.bind(headerLayout)
navHeaderMainBinding.imageViewHeader.setImageResource(R.drawable.imgflag8)
navHeaderMainBinding.textViewHeader1.text = "한국사람"
navHeaderMainBinding.textViewHeader2.text = "나는 가끔 눈물을 흘린다...."
// Step01 ============================================
binding.appBarMain.fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
val drawerLayout: DrawerLayout = binding.drawerLayout
val navView: NavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_content_main)
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.firstFragment, R.id.secondFragment, R.id.thirdFragment
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_content_main)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
- Step01 : nav_header_main.xml에 표시할 데이터를 설정한다.
- appBarConfiguration = AppBarConfiguration( ... ), drawerLayout : setOf에 메뉴의 item을 순서대로 작성한다.
'Computer > Android' 카테고리의 다른 글
[42일차 Android] Code를 이용한 View 생성 (0) | 2023.07.06 |
---|---|
[42일차 Android] XML을 이용한 View 객체 생성 (0) | 2023.07.06 |
[41일차 Android] TabLayout(ViewPager2과 TabLayout 연동) (0) | 2023.07.04 |
[41일차 Android] AppBarLayout (0) | 2023.07.01 |
[41일차 Android] ViewPager2 (0) | 2023.07.01 |