이 글은 이것이 안드로이드다 with 코틀린(개정판)를 참고하여 작성하였습니다.
작성자 : 정서영
개발환경은 Windows, Android Studio입니다.
1. 탭메뉴 뷰페이저와 프래그먼트
- 탭 레이아웃 : 탭 메뉴가 구성된 레이아웃
- 뷰페이저 : 스와이프하면 화면이 이동되도록 구현해준 것
→ 탭 레이아웃과 뷰페이저를 연결해서 화면을 구성
1. 프래그먼트 4개 생성
Fragment A를 만들고 복사해서 레이아웃 fragment_b, _c, _d와 Fragment B, C, D를 생성
2. activity_main에서 Containers의 viewPager를 삽입하고 레이아웃을 match_parent로 설정 ( id는 viewPager )
3. 뷰페이저 안에 프래그먼트를 넣기 위해 FragmentPagerAdapter 클래스 생성. ( FragmentStateAdapter를 상속 )
class FragmentPagerAdapter(val fragmentList:List<Fragment>, fragmentActivity: FragmentActivity)
//자식의 생성자에서 fragmentActivity를 받아서 부모 클래스에 넘겨줌
: FragmentStateAdapter(fragmentActivity){
//꼭 구현해야하는 추상 메소드
override fun getItemCount() = fragmentList.size //아이템 갯수 가져오기
override fun createFragment(position: Int) = fragmentList.get(position)
//목록에서 position에 해당하는 프래그먼트를 반환해서 페이지 그리기
}
4. 화면에 뷰페이저 위젯, 아답터, 프래그먼트 목록을 연결
- 아답터: 데이터 리스트를 입력받아 각 데이터 항목에 해당하는 뷰를 생성
( build.gradle )
buildFeatures{
viewBinding true
}
( MainActivity )
class MainActivity : AppCompatActivity() {
val binding by lazy { ActivityMainBinding.inflate(layoutInflater)} //바인딩 생성
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
//1. 페이지 데이터를 로드
val list = listOf(FragmentA(),FragmentB(),FragmentC(),FragmentD())
//2. 아답터를 생성 ( 프래그먼트 리스트, fragmentActivity를 넣어준다 )
val pagerAdapter = FragmentPagerAdapter(list, this)
//3. 아답터와 뷰페이저 연결
binding.viewPager.adapter = pagerAdapter
}
5. 탭 레이아웃 추가
6. 탭레이아웃과 뷰페이저와 연결
//4. 탭 메뉴의 개수만큼 제목을 목록으로 생성
val titles = listOf("A", "B", "C", "D")
//5. 탭레이아웃과 뷰페이저 연결
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
//tabLayout개수만큼 돌면서 tab을 생성하고 몇번째 position인지 알려줌
tab.text = titles.get(position)
}.attach()
7. with 스코프 함수 사용, tabIndicatorLayoutGravity 속성을 top으로 변경
with(binding){
//3. 아답터와 뷰페이저 연결
viewPager.adapter = pagerAdapter
//4. 탭 메뉴의 개수만큼 제목을 목록으로 생성
val titles = listOf("A", "B", "C", "D")
//5. 탭레이아웃과 뷰페이저 연결
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
//tabLayout개수만큼 돌면서 tab을 생성하고 몇번째 position인지 알려줌
tab.text = titles.get(position)
}.attach()
}
2. 탭메뉴 뷰페이저와 리사이클러뷰
뷰페이저에 리사이클러뷰 어댑터를 사용 ( 리사이클러뷰를 사용하므로 하나의 레이아웃만으로 구현 가능 )
1. 뷰페이저 생성 ( Containers → ViewPager )
2. build. gradle 파일에서 뷰바인딩 설정
3. item_viewpager 레이아웃 생성, textView 삽입
4. MainActivity에서 아이템 레이아웃을 사용하는 어댑터 클래스 생성, 어댑터와 뷰페이저 연결
class MainActivity : AppCompatActivity() {
//바인딩클래스의 inflate 함수로 xml 파일을 객체화
val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
//1.데이터 로드
val list = listOf("월", "화", "수", "목", "금", "토", "일")
//2.어댑터를 생성해서 데이터를 넘겨줌
val pagerAdapter = CustomPagerAdapter(list)
//3.어댑터와 뷰페이저를 연결
binding.viewPager.adapter = pagerAdapter
}
}
//어댑터 클래스 생성: RecyclerView의 Adapter를 상속 <사용할 뷰 홀더>
class CustomPagerAdapter(val textList:List<String>) : RecyclerView.Adapter<CustomPagerAdapter.Holder>(){
//Holder 만들기 (RecyclerView의 ViewHolder를 상속)
class Holder(val binding: ItemViewpagerBinding) : RecyclerView.ViewHolder(binding.root) {
fun setItem(text: String) {
binding.textView.text = text //받아온 바인딩 객체의 textview에 각각의 text를 set
}
}
///implement members -> 추상 메소드들 구현
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
//ItemViewPagerBinding을 inflate해서 바인딩 객체 생성
val binding = ItemViewpagerBinding.inflate(LayoutInflater.from(parent.context),parent,false)
return Holder(binding)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
//돌면서 각각의 text를 set
holder.setItem(textList.get(position))
}
override fun getItemCount() = textList.size
}
5. 탭 레이아웃 연결
//4. 탭 타이틀 목록 생성 = 위의 리스트 사용
//5. 탭레이아웃과 뷰페이저 연결
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
tab.text = list.get(position)
}.attach()
6. 페이지 클래스를 만들어서 구현하기 위해 아이템 레이아웃 변경 ( 두개의 textView : textDay, textWeather )
7. 페이지 데이터 클래스를 생성하고 해당 클래스에서 데이터 로드해오기
class MainActivity : AppCompatActivity() {
val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
//1.데이터 로드
val list = loadData()
//2.어댑터를 생성, 데이터 넘겨줌
val pagerAdapter = CustomPagerAdapter(list)
//3.어댑터와 뷰페이저를 연결
binding.viewPager.adapter = pagerAdapter
//4. 탭 타이틀 목록 생성 = 위의 리스트 사용
val titles = listOf("월", "화", "수", "목", "금", "토", "일")
//5. 탭레이아웃과 뷰페이저 연결
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
tab.text = titles.get(position)
}.attach()
}
fun loadData() : List<Page> {
val pageList = mutableListOf<Page>()
pageList.add(Page(1,"흐림"))
pageList.add(Page(2,"맑음"))
pageList.add(Page(3,"구름"))
pageList.add(Page(4,"비"))
pageList.add(Page(5,"눈"))
pageList.add(Page(6,"태풍"))
pageList.add(Page(7,"안개"))
return pageList
}
}
class CustomPagerAdapter(val pageList:List<Page>) : RecyclerView.Adapter<CustomPagerAdapter.Holder>(){
class Holder(val binding: ItemViewpagerBinding) : RecyclerView.ViewHolder(binding.root) {
fun setItem(page: Page) {
with(binding){
textDay.text = "${page.day} 일"
textWeather.text = page.weather
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val binding = ItemViewpagerBinding.inflate(LayoutInflater.from(parent.context),parent,false)
return Holder(binding)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
holder.setItem(pageList.get(position))
}
override fun getItemCount() = pageList.size
}
//데이터 클래스 선언
data class Page( val day: Int, val weather: String)
'GDSC HUFS 3기 > Android with Kotlin Team 6' 카테고리의 다른 글
[6팀] 코틀린 안드로이드 기초강의 45 쓰레드 타이머, 46 코루틴 이미지 다운로드 (0) | 2021.12.05 |
---|---|
[6팀] 코틀린 안드로이드 기초강의 41 Android와 SQLite 데이터 베이스 (0) | 2021.11.30 |
[6팀] 코틀린 안드로이드 기초강의 41 Room (0) | 2021.11.26 |
[6팀]코틀린 안드로이드 기초강의 40 SharedPreferences (0) | 2021.11.26 |
[6팀] 코틀린 안드로이드 기초 강의 33-34 커스텀 뷰, 커스텀 위젯 (0) | 2021.11.17 |