[Android / Kotlin] ViewPager2와 TabLayout

Subeen·2024년 1월 15일
0

Android

목록 보기
42/73

새로운 팀 프로젝트 주제로 주소록이 주어졌다. 과제의 필수 기능 중 하나인 ViewPager2TabLayout을 사용하여 화면을 슬라이드 하고 선택한 탭에 해당하는 화면으로 전환하는 기능을 구현하였다.

결과 화면

의존성 추가

  • ViewPager2를 사용하기 위해 build.gradle(앱 수준)에서 의존성을 추가한다.
dependencies {
	...
    
    // viewPager2
    implementation("androidx.viewpager2:viewpager2:1.0.0")
}

layout

TabLayout 옵션

  • 텍스트 사이즈 조정
    • valudes/styles.xml 위치에 style을 생성한 후 TabLayout에 적용한다.
// valudes/styles.xml
<style name="tabText" parent="TextAppearance.Design.Tab">
	<item name="android:textSize">10sp</item>
</style>
// TabLayout
app:tabTextAppearance="@style/tabText"
  • Tab 선택 시 텍스트 색상 변경
    • default 색상은 tabTextColor로 설정하며, 선택 시 색상을 변경하기 위해서 tabSelectedTextColor에 색상을 설정한다.
app:tabTextColor="@color/colorUnselect"
app:tabSelectedTextColor="@color/colorSelect"
  • Indicator 위치 및 색상 변경
    • tabIndicatorGravity를 통해 Indicator 위치를 설정하며, 색은 IndicatorColor로 변경한다.
app:tabIndicatorGravity="top"
app:tabIndicatorColor="@color/colorSelect"
  • Tab을 선택했을 때 해당 Tab이 회색으로 누른 순간만큼 변하는 현상이 있는데, 이를 제거하기 위해서는 투명색으로 설정한다.
app:tabRippleColor="@color/colorTransparent"
  • Tab을 선택했을 때 해당 아이콘의 색상 변경
    • res/color에 selector파일을 생성하고 TabLayout의 tabIconTint에 적용한다.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/tab_select" android:state_selected="true" />
    <item android:color="@color/tab_basic" />
</selector>

layout_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@id/tabLayout"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="@color/widget"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:tabIconTint="@color/selector_tab_icon_color"
        app:tabIndicatorColor="#00ffffff" />

</androidx.constraintlayout.widget.ConstraintLayout>

Adapter

ViewPager2가 제공하는 어댑터 클래스인 FragmentStateAdapter를 상속받아 사용한다.
FragmentStateAdapter는 각 페이지를 프래그먼트로 구성하고 싶을 때 사용한다.

class ViewPagerAdapter(fragmentActivity: FragmentActivity) :
    FragmentStateAdapter(fragmentActivity) {
    private val fragments: ArrayList<Fragment> = ArrayList()

	// 페이지 개수 
    override fun getItemCount(): Int {
        return fragments.size
    }

	/*
     * 파라미터 : position값, 반환 값 : Fragment 인스턴스 
     */
    override fun createFragment(position: Int): Fragment {
        return fragments[position]
    }

    fun addFragment(fragment: Fragment) {
        fragments.add(fragment)
        notifyItemInserted(fragments.size - 1)
    }

    fun removeFragment() {
        fragments.removeLast()
        notifyItemRemoved(fragments.size)
    }
}

MainActivity

class MainActivity : AppCompatActivity() {
    private val binding: ActivityMainBinding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }

    private val icons =
        listOf(
            R.drawable.ic_tablayout_favorite_all,
            R.drawable.ic_tablayout_contact_all,
            R.drawable.ic_tablayout_dialpad
        )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        initView()
    }

    private fun initView() {
        requestContactPermission()
        getContacts()

        // ViewPager Adapter 생성
        val viewPagerAdapter = ViewPagerAdapter(this@MainActivity)
        viewPagerAdapter.addFragment(FavoriteFragment()) // 즐겨찾기 Fragment 추가 
        viewPagerAdapter.addFragment(ContactListFragment()) // 연락처 Fragment 추가
        viewPagerAdapter.addFragment(DialPadFragment()) // 키패드 Fragment 추가 

        // Adapter 연경
        binding.viewPager.apply {
            adapter = viewPagerAdapter
            registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
                override fun onPageSelected(position: Int) {
                    super.onPageSelected(position)
                }
            })
        }

        // ViewPager TabLayout 연결
        TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
            tab.setIcon(icons[position])
        }.attach()

    }
}

[Android] TabLayout textsize & Icon 색상 & Indicator 변경 방법

profile
개발 공부 기록 🌱

0개의 댓글