-
[Android] Tab Layout 구현 (Tab 선택 시, icon & text 색상 변경)안드로이드 2024. 5. 16. 09:39
✏️ TIL(Today I Learned)
하단에 Tab Layout을 만들어서, 클릭 시 선택된 탭의 아이콘과 텍스트의 색이 변경되면서 프래그먼트가 전환되도록 했다.
레이아웃부터 만들어준다.
상단에 툴바, 가운데에 뷰페이저, 하단에 탭으로 구성했다.
그리고 한 가지 주의해야할 점이있다.
메인 엑티비티에서 클릭된 탭의 텍스트 색을 변경하려고 아무리 해도 적용되지 않았는데,
xml의 TabLayout에 tabSelectedTextColor 속성을 추가하니 적용되었다...
<?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=".presentation.main.MainActivity"> <androidx.appcompat.widget.Toolbar android:id="@+id/tb_main" android:layout_width="match_parent" android:layout_height="56dp" android:background="@color/mainRed" app:titleTextColor="@color/white" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <ImageView android:id="@+id/tb_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:adjustViewBounds="true" android:scaleType="fitCenter" android:padding="12dp" android:src="@drawable/ic_logo" /> <TextView android:id="@+id/tb_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:text="@string/main_toolbar_title" android:textColor="@color/white" android:textStyle="bold" android:textSize="22dp"/> </androidx.appcompat.widget.Toolbar> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/vp_main" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintBottom_toTopOf="@+id/tl_main" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tb_main" /> <com.google.android.material.tabs.TabLayout android:id="@+id/tl_main" android:layout_width="0dp" android:layout_height="wrap_content" app:tabIndicatorHeight="0dp" style="@style/tabLayout" app:tabSelectedTextColor="@color/white" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
그리고 TabModel을 만든다.
프래그먼트, 타이틀 리소스 ID, 아이콘 리소스 ID를 필드로 가진다.
data class MainTabModel( val fragment: Fragment, @StringRes val title: Int, @DrawableRes val icon: Int )
그 다음, ViewPagerAdapter를 만들었다.
FragmentStateAdapter를 상속받는 어댑터 클래스로, MainActivity의 ViewPager2에 연결한다.
- MainTabModel 객체의 리스트
- getItemCount() 함수를 통해 전체 탭의 개수를 반환
- createFragment() 함수를 통해 해당 위치에 해당하는 프래그먼트를 생성
- getTitle(), getTabIcon()를 통해 각 탭의 제목과 아이콘을 반환
class MainViewPagerAdapter( fragmentActivity: FragmentActivity ) : FragmentStateAdapter(fragmentActivity) { private val fragments = listOf( MainTabModel(SearchFragment.newInstance(), R.string.main_tab_search_title, R.drawable.ic_search), MainTabModel(HomeFragment.newInstance(), R.string.main_tab_home_title, R.drawable.ic_home), MainTabModel(VideoDetailFragment.newInstance(), R.string.main_tab_myvideos_title, R.drawable.ic_my_videos), ) override fun getItemCount(): Int = fragments.size override fun createFragment(position: Int): Fragment = fragments[position].fragment fun getTitle(position: Int): Int = fragments[position].title fun getTabIcon(position: Int): Int = fragments[position].icon }
마지막으로, MainActivity이다.
- ActivityMainBinding을 사용하여 레이아웃과의 바인딩을 처리
- viewPagerAdapter를 초기화
- onCreate()에서 화면을 설정하고 initView()를 호출
- initView():
ViewPager2와 TabLayout을 연결하고, 각 탭에 대한 아이콘 및 텍스트를 설정
addOnTabSelectedListener를 통해, 탭 선택에 따라 아이콘의 색상을 변경
class MainActivity : AppCompatActivity() { private val binding: ActivityMainBinding by lazy { ActivityMainBinding.inflate(layoutInflater) } private val viewPagerAdapter by lazy { MainViewPagerAdapter(this) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(binding.root) initView() } private fun initView() = with(binding) { // TabLayout x ViewPager2 vpMain.adapter = viewPagerAdapter vpMain.offscreenPageLimit = viewPagerAdapter.itemCount TabLayoutMediator(tlMain, vpMain) { tab, position -> tab.setText(viewPagerAdapter.getTitle(position)) tab.setIcon(viewPagerAdapter.getTabIcon(position)) }.attach() tlMain.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { override fun onTabSelected(tab: TabLayout.Tab?) { tab?.let { it.icon?.setTint(getColor(R.color.white)) } } override fun onTabUnselected(tab: TabLayout.Tab?) { tab?.let { it.icon?.setTint(getColor(R.color.darkRed)) } } override fun onTabReselected(tab: TabLayout.Tab?) { // 재선택 시 } }) tlMain.getTabAt(1)?.select() // Home을 default로 설정 } }
'안드로이드' 카테고리의 다른 글