새로운 팀 프로젝트 주제로 주소록이 주어졌다. 과제의 필수 기능 중 하나인
ViewPager2
와TabLayout
을 사용하여 화면을 슬라이드 하고 선택한 탭에 해당하는 화면으로 전환하는 기능을 구현하였다.
dependencies {
...
// viewPager2
implementation("androidx.viewpager2:viewpager2:1.0.0")
}
// valudes/styles.xml <style name="tabText" parent="TextAppearance.Design.Tab"> <item name="android:textSize">10sp</item> </style> // TabLayout app:tabTextAppearance="@style/tabText"
app:tabTextColor="@color/colorUnselect"
app:tabSelectedTextColor="@color/colorSelect"
app:tabIndicatorGravity="top"
app:tabIndicatorColor="@color/colorSelect"
app:tabRippleColor="@color/colorTransparent"
<?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>
<?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>
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)
}
}
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()
}
}