정상에서 IT를 외치다

[Android, TabLayout] 탭 레이아웃의 모든것! 본문

안드로이드

[Android, TabLayout] 탭 레이아웃의 모든것!

Black-Jin 2018. 6. 4. 17:40
반응형

안녕하세요. 블랙진입니다.


이번에는 탭 레이아웃의 모든것! 포스팅 해보고자 합니다. 짝! 짝! 짝! 짝!

먼저 아래 이미지는 구현 결과물 입니다.





시작하기에 앞서 이전 포스팅의 "뷰페이저 만들기" 예제 파일이 필요합니다.(A~E Fragment 를 가지는 뷰페이저 만들기 입니다.)

뷰페이저에 대해 공부하실 분은 위 예제를 먼저 따라해 주시고 아닌 분은 MyViewPager 에서 예제 파일을 다운받아주세요.


자 그럼 머테리얼 디자인중 하나인 탭 레이아웃의 모든걸 배워보겠습니다. > ,. < //

(모든 코드는 kotlin 으로 작업하였습니다.)




1. APP 단계의 build.gradle 에 아래 코드를 추가해 주세요.


build.gradle

implementation 'com.android.support:design:27.1.1'

(27.1.1 은 supportLibrary 의 버전을 나타냅니다. 본인 프로젝트에 맞는 버전을 입력해 주세요)




2. style 에 TagTheme 를 생성해 줍니다.


style.xml

<style name="TabTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#f5a623</item> <!-- 배경 -->

<item name="android:textColorPrimary">@android:color/white</item> <!-- 탭바 선택된 텍스트 -->
<item name="android:textColorSecondary">@android:color/black</item> <!-- 탭바 텍스트 -->

<item name="colorAccent">@android:color/white</item> <!-- 하단 움직이는 바 색-->
</style>

TabLayout 의 배경 색과 글자 색은 Theme 를 통해서 변경해 주어야 합니다.

각각의 역활은 주석으로 달아놓았습니다.




3.  XML 에 TabLayout 을 추가해 줍니다.


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/TabTheme">

<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</android.support.design.widget.AppBarLayout>

<android.support.v4.view.ViewPager
android:id="@+id/vpMainActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</android.support.design.widget.CoordinatorLayout>

여기서 중요한 점은 AppBarLayout 안에 TabLayout 을 위치시켜야 합니다. 

또한 AppBarLayout 에 TabTheme 를 설정해 주어야 원하는 동작을 얻을 수 있습니다.




4. MainActivity 에 탭레이아웃을 연결해 줍니다.


MainActivity.kt

class MainActivity : AppCompatActivity() {

private val adapter by lazy { MainAdapter(supportFragmentManager) }

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

// 뷰페이저 어댑터 연결
vpMainActivity.adapter = MainActivity@adapter

// 탭 레이아웃에 뷰페이저 연결
tabLayout.setupWithViewPager(vpMainActivity)

}
}




5. MainAdapter 에서 getPageTitle 을 오버라이딩 해줍니다.


MainAdapter.kt

class MainAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {

private val fragmentTitleList = mutableListOf("A","B","C","D","E")

override fun getItem(position: Int): Fragment? {

return when(position) {

0 -> AFragment()

1 -> BFragment()

2 -> CFragment()

3 -> DFragment()

4 -> EFragment()

else -> null
}

}

// 생성 할 Fragment 의 개수
override fun getCount() = 5

override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
super.destroyItem(container, position, `object`)
//Log.e("FragmentPagerAdapter", "destroyItem position : $position")
}

override fun getPageTitle(position: Int): CharSequence? {
return fragmentTitleList[position]
}

}

사용하고 있는 예제는 A ~ E 까지의 5개의 프래그먼트를 가진 뷰페이저 입니다. 따라서 fragmentTitleList 에는 A ~ E 까지의 변수를 넣어주었습니다.

getPageTitle 을 통해서 탭 레이아웃 전환에 따른 포지션값을 받아 처리할 수 있습니다. 




 - 중간결과물



짜잔!!  5개의 탭 으로 이루어진 레이아웃이 연동됩니다. 물론 뷰페이저 전환에 따라 탭 레이아웃이 반응 합니다.


TabTheme 에서 설정해 주었던 값들이 잘 보이고 있죠? 선택된 A 는 하얀색 텍스트, 나머지 B,C,D,E 는 검정색 텍스트 입니다.

A 하단에 있는 바 또한 하얀색으로 변경되었습니다.


배경은 색은 #f5a623 색으로 잘 적용 되었음을 확인할 수 있습니다.


하지만! 여기서 끝나면 탭 레이아웃의 모든게 아니죠


이번에는 이미지를 넣어 보도록 하겠습니다. 제가 사용한 아이콘은 icons - Material Design 에서 받아왔습니다. 흰색과 검정색을 선택하여 다운받을 수 있으니 참고해 주세요. (a,b,c,d,e 에 사용한 아이콘의 이름은 각각 ic_a,  ic_b,  ic_c,  ic_d,  ic_e 입니다. 검정색 이미지는 뒤에 _black 붙였습니다)




6. 탭 레이아웃에 이미지 추가하기


MainActivity.kt

tabLayout.getTabAt(0)?.setIcon(R.drawable.ic_a)
tabLayout.getTabAt(1)?.setIcon(R.drawable.ic_b_black)
tabLayout.getTabAt(2)?.setIcon(R.drawable.ic_c_black)
tabLayout.getTabAt(3)?.setIcon(R.drawable.ic_d_black)
tabLayout.getTabAt(4)?.setIcon(R.drawable.ic_e_black)

간단합니다. MainActivity 에서 tabLayout 에 포지션별로 추가해 주면 됩니다. 

초기화 할 때 getTabAt(0) 에는 ic_a_black 이 아닌 ic_a 넣어주었습니다. 그 이유는 첫번째가 선택된 상태에서 시작되기 때문에 첫번 째 아이콘은 선택되었을 때 보여질 아이콘 ic_a 로 설정하였습니다.





7. 뷰 페이저 전환에 따른 이미지 변화 연동

vpMainActivity.addOnPageChangeListener(object : ViewPager.OnPageChangeListener{
override fun onPageScrollStateChanged(state: Int) {
}

override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
}

override fun onPageSelected(position: Int) {

tabLayout.getTabAt(0)?.setIcon(R.drawable.ic_a_black)
tabLayout.getTabAt(1)?.setIcon(R.drawable.ic_b_black)
tabLayout.getTabAt(2)?.setIcon(R.drawable.ic_c_black)
tabLayout.getTabAt(3)?.setIcon(R.drawable.ic_d_black)
tabLayout.getTabAt(4)?.setIcon(R.drawable.ic_e_black)

when(position) {

0 -> tabLayout.getTabAt(0)?.setIcon(R.drawable.ic_a)
1 -> tabLayout.getTabAt(1)?.setIcon(R.drawable.ic_b)
2 -> tabLayout.getTabAt(2)?.setIcon(R.drawable.ic_c)
3 -> tabLayout.getTabAt(3)?.setIcon(R.drawable.ic_d)
4 -> tabLayout.getTabAt(4)?.setIcon(R.drawable.ic_e)
}



}

})

뷰 페이저에는 화면 전환에 따른 포지션을 받을 수 있는 addOnPageChangeListener가 있습니다. 

화면이 전환 되었을 때 모든 이미지를 black 으로 변경하고 선택된 화면의 포지션만 다른 이미지로 변경하였습니다.


이렇게 까지만 해주시면 모든 화면전환에 맞게 이미지도 변경되는걸 확인 하실 수 있습니다. 

아래는 MainAcitivty 전체 코드 입니다.




참고로 이미지만 보이고 텍스트를 지우고 싶은 때는 MainAdapter 의 getPageTitle 의 return 을 null 로 설정하시면 됩니다.


MainAdapter.kt

override fun getPageTitle(position: Int): CharSequence? {
//return null to display only the icon
return null
}


이렇게 만든것도 이쁜것 같아 짤 투척~!







자 이제 탭 레이아웃의 기본과 커스텀 하는 법까지 모두 포스팅 완료 했습니다. 여기까지 따라오는데 큰 문제는 없으셨나요?? 


혹시 못 따라 오신 분을 위해 완성 코드를 깃허브에 공유하도록 하겠습니다. 그럼 안뇨옹~!




<참고 자료>


TabLayout example

반응형
Comments