[Android] Sunflower 클론코딩 (22.06.06)

유재민·2022년 6월 5일
0

Sunflower

목록 보기
5/12
post-thumbnail

Toolbar in Fragment

// HomeViewPagerFragment.kt

override fun onCreateView(..): View{
		...
		(activity as AppCompatActivity).setSupportActionBar(binding.toolbar)
}

엑티비티에서 툴바를 선언하는 것이 아닌 ViewPagerFragment에 선언한다.

(현재 Acitivity에서 Navigation에 첫페이지가 ViewPagerFragment로 설정되어있음)

ViewPager + TabLayout

  1. PagerAdapter
  • 각 Page index 선언
// SunflowerPagerAdapter.kt

const val MY_GARDEN_PAGE_INDEX = 0
const val PLANT_LIST_PAGE_INDEX = 1

class 밖에 const val로 선언

const val : 컴파일 시점에 결정되는 상수 (자바의 static final의 형태, val은 런타임 시점)

→ 보통 최상위 레벨에 선언하거나 object로 선언한 클래스에서만 사용 가능하다.

  • FragmentStateAdapter
class SunflowerPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
		...
}

ViewPager와 TabLayout을 연결하기 위해 필요한 함수이다.

RecyclerView.Adapter가 부모 클래스로 존재하며 RecyclerView의 Paging 버전 같은 느낌이다.

  • Mapping
private val tabFragmentsCreators: Map<Int, () -> Fragment> = mapOf(
    MY_GARDEN_PAGE_INDEX to { GardenFragment() },
    PLANT_LIST_PAGE_INDEX to { PlantListFragment() }
)

각각의 Fragment에 ViewPager index를 매핑한다.

0 → GradenFragment
1 → PlantListFragment

  • getItemCount()
override fun getItemCount() = tabFragmentsCreators.size

RecyclerView Adapter 가 부모 클래스인 만큼 getItemCount() 함수를 통해 현재 아이템의 개수를 선언한다.

  • createFragment()
override fun createFragment(position: Int): Fragment {
		return tabFragmentsCreators[position]?.invoke() ?: throw IndexOutOfBoundsException()
}

각 position에 맞는 Fragment를 생성

Map<Int, () → Fragment> 형식으로 매핑되어 있어 invoke() 필요

null 값이 들어오면 ?: 엘비스 연산자로 IndexOutOfBoundsException 발생

  1. TabLayout Icon 추가
  • selector xml 생성
<!-- garden_tab_selector.xml -->

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_my_garden_active" android:state_selected="true"/>
    <item android:drawable="@drawable/ic_my_garden_inactive"/>
</selector>

android:state_selected="true" : 기본 활성화 상태

<!-- ic_my_garden_active.xml -->

<vector android:height="28dp" android:viewportHeight="21"
    android:viewportWidth="18" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path
        android:pathData="..."
        android:fillColor="?attr/colorOnPrimary"
        android:fillType="nonZero" />
</vector>

fillType 속성은 SDK 24 이상에서만 사용할 수 있다.

그러나, 이 프로젝트는 minSdkVersion 이 21이므로 해당 config를 추가해준다.

// build.gradle (:app)

android {
		...
		defaultConfig {
		...
		vectorDrawables.useSupportLibrary true
		}
}

Using vector assets in Android apps

  • getTabIcon 함수 생성
// HomeViewPagerFragment.kt

private fun getTabIcon(position: Int): Int {
    return when (position) {
        MY_GARDEN_PAGE_INDEX -> R.drawable.garden_tab_selector
        PLANT_LIST_PAGE_INDEX -> R.drawable.plant_list_tab_selector
        else -> throw IndexOutOfBoundsException()
    }
}
  1. TabLayout Title 추가
private fun getTabTitle(position: Int): String? {
    return when (position) {
        MY_GARDEN_PAGE_INDEX -> getString(R.string.my_garden_title)
        PLANT_LIST_PAGE_INDEX -> getString(R.string.plant_list_title)
        else -> null
    }
}
  1. TabLayoutMediator

: TabLayout 과 ViewPager2의 연동을 도와주는 객체

TabLayoutMediator(tabLayout, viewPager) { tab, position ->
    tab.setIcon(getTabIcon(position))
    tab.text = getTabTitle(position)
}.attach()

람다식을 통해 각 tab에 알맞은 아이콘과 title을 설정한다.

profile
유잼코딩

0개의 댓글