일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 베드테이블
- 리얼하다
- 지지않는다는말
- 슬기로운 온라인 게임
- 끝말잇기
- 커스텀린트
- 한단어의힘
- 프래그먼트
- 함수형 프로그래밍
- 북한살둘레길
- 소프시스
- 목적중심리더십
- 좌식테이블
- 1일1커밋
- 브런치작가되기
- 소프시스 밤부 좌식 엑슬 테이블
- 어떻게 나답게 살 것인가
- 아비투스
- 한달브런치북만들기
- 면접
- 베드트레이
- 캐치마인드
- 재택근무
- 안드로이드
- T자형인재
- 목적 중심 리더십
- 한달어스
- 자취필수템
- 테트리스
- 한달독서
- Today
- Total
정상에서 IT를 외치다
[Android, TabLayout] 탭 레이아웃의 모든것! 본문
안녕하세요. 블랙진입니다.
이번에는 탭 레이아웃의 모든것! 포스팅 해보고자 합니다. 짝! 짝! 짝! 짝!
먼저 아래 이미지는 구현 결과물 입니다.
시작하기에 앞서 이전 포스팅의 "뷰페이저 만들기" 예제 파일이 필요합니다.(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
}
이렇게 만든것도 이쁜것 같아 짤 투척~!
자 이제 탭 레이아웃의 기본과 커스텀 하는 법까지 모두 포스팅 완료 했습니다. 여기까지 따라오는데 큰 문제는 없으셨나요??
혹시 못 따라 오신 분을 위해 완성 코드를 깃허브에 공유하도록 하겠습니다. 그럼 안뇨옹~!
<참고 자료>
'안드로이드' 카테고리의 다른 글
[Android, StickyHeader] StickyHeader in RecyclerView (1) | 2018.06.11 |
---|---|
[Android, jetpack] Android Jetpack (0) | 2018.06.08 |
[Android, setUserVisibleHint] 뷰페이저에서 보인 화면만 데이터 받아오기 (0) | 2018.06.04 |
[Android, FragmentPagerAdapter] FragmentPagerAdapter 와 FragmentStatePagerAdapter 의 차이 (1) | 2018.06.04 |
[AndroidManifest] singleTask, noHistroy, parentActivityName 에 대해서 (0) | 2018.06.01 |