탭 레이아웃은 탭(tab)으로 구분하는 화면에서 탭 버튼을 배치하는 레이아웃이다. 탭 버튼을 다양하게 표시하고자 사용하는 뷰이다.
구글 플레이 스토어를 들어가보면 탭이 적으면 그냥 나열되는데 탭이 많으면 옆으로 스크롤 해서 볼 수 있다.
탭 버튼이 많으면 이처럼 스크롤되게 제공해야 한다. 탭버튼을 가로등분으로 제공할수도 있다. 이런 설정들을 탭 레이아웃을 통해 출력한다.
// 탭 레이아웃 등록
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
androdi:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout // 탭 레이아웃 선언
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout // FrameLayout 선언
android:id="@+id/tabContent"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
위 코드는 탭 화면을 만드는 레이아웃 XML 파일이다. TabLayout과 FrameLayout을 선언했다. 사용자가 TabLayout으로 구성한 탭 버튼을 선택하면 FrameLayout 위치에 탭의 내용을 출력한다.
// 코드에서 탭 버튼 정의
val tab1: TabLayout.Tab = tabLayout.newTab() // 탭 버튼 객체 생성
tab1.text="Tab1"
tabLayout.addTab(tab1) // 탭 레이아웃에 탭 버튼 추가
val tab2: TabLayout.Tab = tabLayout.newTab()
tab2.text="Tab2"
tabLayout.addTab(tab2)
val tab3: TabLayout.Tab = tabLayout.newTab()
tab3.text="Tab3"
tabLayout.addTab(tab3)
탭 레이아웃에 추가되는 탭 버튼은 TabLayout.newTab() 함수로 만들어지는 TabLayout.Tab 객체이며 이 객체의 text 속성으로 문자열을, icon 속성으로 이미지를 지정한다. 그리고 이 Tab 객체를 TabLayout.addTab() 함수의 매개변수로 지정하여 탭 버튼을 추가한다.
위 코드는 TabLayout에 Tab 객체를 3개 추가했으므로 탭 버튼이 3개인 탭 화면을 만든다. 그런데 만약 탭 레이아웃의 탭 버튼을 동적으로 만들 필요가 없다면 앞의 예처럼 탭 버튼을 코드에서 정의하지 않고 레이아웃 XML 파일의 TabItem으로 정의해도 된다. TabLayout 하위에 추가되는 TabItem 하나가 탭 버튼 하나를 의미한다.
// XML 파일에서 탭 버튼 정의
<com.google.android.material.tabs.TabLayout // 탭 레이아웃 선언
android:id="@id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabItem // TabItem으로 레이아웃 파일에서 탭 정의
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tab1" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tab2" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tab3" />
</com.google.android.material.tabs.TabLayout>
사용자가 탭 버튼을 선택할 때 출력해야 하는 내용은 코드에서 탭 버튼의 이벤트 핸들러에 명시해야 한다.
// 탭 버튼 이벤트 처리
tabLayout.addOnTabSelectedListener(object: TabLayout.OnTabSelectedListener {
// 탭 버튼을 선택할 때 이벤트
override fun onTabSelected(tab: TabLayout.Tab?) {
// onTabSelected가 이벤트 처리?
val transaction = supportfragmentmanager.beginTransaction()
when (tab?.text) {
"Tab1"-> transaction.replace(R.id.tabContent,OneFragment())
"Tab2"-> transaction.replace(R.id.tabContent,TwoFragment())
"Tab3"-> transaction.replace(R.id.tabContent,ThreeFragment())
}
transaction.commit()
}
// 선택된 탭 버튼을 다시 선택할 때 이벤트
override fun onTabReselected(tab: TabLayout.Tab?) {
(... 생략 ...)
}
// 다른 탭 버튼을 눌러 선택된 탭 버튼이 해제될 때 이벤트
override fun onTabunselected(tab: TabLayout.Tab?) {
(... 생략 ...)
}
})
TabLayout을 이용해 탭 버튼 3개를 출력한 예이다. 탭 레이아웃은 기본으로 탭 버튼을 가로등분으로 배치한다. 그러므로 3개의 버튼이 가로 3등분으로 출력된다.
TabLayout의 addOnTabSelectedListener() 함수를 이용해 이벤트 핸들러 객체를 지정해 준다. 탭 버튼 이벤트 핸들러 객체는 TabLayout.OnTabSelectedListener를 구현한 객체여야 하며 각 이벤트 콜백 함수의 매개변수는 현재 이벤트가 발생한 Tab 객체이다.
탭 레이아웃은 다음과 같은 속성으로 탭 버튼을 다양하게 출력할 수 있다.
탭 버튼 정렬하기
tabGravity는 탭 버튼을 정렬하는 속성이다. 기본값은 fill 이며 탭 버튼을 가로로 등분하여 배치한다. center는 탭 버튼을 가운데 정렬한다.
스크롤 설정하기
tabMode 속성은 탭 버튼을 스크롤할 수 있는지를 설정한다. 기본값은 fixed인데 스크롤을 지원하지 않는다는 의미이다. 만약 scrollable로 설정하면 탭 버튼이 왼쪽부터 나열되고 모두 출력할 수 없다면 자동으로 가로 스크롤이 생긴다.
뷰 페이저 연동하기
탭 레이아웃으로 탭 화면을 만들면서 11장에서 살펴본 뷰 페이저와 연동할 수 있다. 탭 레이아웃과 뷰 페이저는 화면을 여러 장 제공하는 용도이므로 둘을 연동하는 일이 많다. 예를 들어 Facebook 화면은 탭버튼을 눌러 화면을 전환할 수도 있지만 탭 버튼 아래 콘텐츠 부분을 뷰 페이저로 제공하여 스와이프로 화면을 전환하게 할 수도 있다. 이처럼 탭 레이아웃은 뷰 페이저와 연동을 지원한다.
// 탭 레이아웃과 뷰 페이저 등록
<LinearLayout xmlns:android="hattp://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout // 탭 레이아웃 선언
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable">
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager2.widget.ViewPager2 // 뷰 페이저2 등록
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
레이아웃 XML 파일에 TabLayout과 ViewPager2를 등록한 후 코드에서 TabLayoutMediator를 이용해 둘을 연동하면 된다.
// 탭 레이아웃과 뷰 페이저 연동
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
tab.text = "Tab${(position + 1)}"
}.attach()
TabLayoutMediator 생성자의 매개변수로 연동하고자 하는 탭 레이아웃과 뷰 페이저 객체를 전달한다. 이렇게 하면 뷰 페이저의 화면이 3개이면 탭 버튼도 자동으로 3개가 나온다. 또한 사용자가 탭 버튼을 누르는 순간 뷰 페이저 화면이 자동으로 조정되며, 반대로 사용자가 뷰 페이저 화면을 넘기는 순간 탭 버튼도 자동으로 조정된다. 이처럼 뷰 페이저와 연동하면 탭 버튼의 문자열은 3번째 매개변수로 전달하는 함수에서 지정할 수 있다. 이 함수의 매개변수는 탭 버튼 객체(tab)와 화면에서 위치(position)이므로 이를 이용해 탭 버튼의 문자열 등을 지정하면 된다.
'깡샘 코틀린' 카테고리의 다른 글
12-4 확장된 플로팅 액션 버튼 (0) | 2023.06.30 |
---|---|
12-3 내비게이션 뷰 - 드로어 화면 구성 (0) | 2023.06.30 |
12-1 앱바 사용하기 (0) | 2023.06.30 |
11-6 드로어 레이아웃 - 옆에서 열리는 화면 구성 (0) | 2023.06.29 |
11-5 뷰 페이저2 - 스와이프로 넘기는 화면 구성 (0) | 2023.06.29 |