상세 컨텐츠

본문 제목

[Kotlin] 위젯 - ViewPager2

Mobile/Kotlin

by 클리엘 클리엘 2020. 12. 23. 09:53

본문

728x90

ViewPager2는 스와이프(Swipe)를 통해 화면 전환을 구현할 때 사용되는 위젯입니다. 본래 ViewPager가 있었으나 여러 가지 문제로 현재는 ViewPager2로 완전히 대체되었습니다. 그럼 이번에는 ViewPager2에 대한 간단한 사용방법을 알아보도록 하겠습니다.

 

ViewPager2에서 화면전환을 위해서 Fragment를 이용할 수 있습니다. 이런 경우 필요한 화면만큼 Fragment화면을 추가해야 합니다. 이번 예제에서는 대략 3개 정도의 화면을 만들어 보도로 하겠습니다. 다음과 같이 app -> java 아래의 패키지에서 마우스 오른쪽 버튼을 눌러 New -> Fragment -> Fragment(Blank)를 선택합니다.

 

Fragment Name에서 이름을 MyFragment1 이라고 지정합니다. 물론 다른 임의의 이름을 지정해도 상관없습니다.

 

Fragment가 추가되면 기본적으로 TextView하나를 달고 Fragment가 생성되는데 TextView의 내용을 Fragment에서 구분할 수 있도록 임의로 수정합니다.

 

이러한 방법으로 Fragment를 2개정도 더 만들어 이름을 지을 때 번호를 1부터 3까지 지정해 만듭니다.

 

MainActivity를 열고 기본적으로 올라가 있는 TextView를 제거한 다음 Palette의 Containers에서 ViewPager2를 끌어다 놓습니다. 처음 ViewPager2를 사용하게 되면 Library를 내려받아야 한다는 경고창이 뜰 수 있는데 OK 버튼을 눌러 Library를 다운로드하도록 합니다. ViewPager2 추가가 완료되면 id를 지정합니다. 예제에서는 myViewPager로 하였습니다.

 

이제 ViewPager2와 연결할 Adapter를 만들어 위에서 생성한 Fragment를 ViewPager2에서 보여줄 수 있도록 해야합니다. app -> java -> 패키 지명에서 마우스 오른쪽 버튼을 눌러 New -> Kotlin File/Class를 선택합니다.

 

이어지는 화면에서 Class를 선택하고 이름을 FragmentAdapter로 지정합니다.

 

Class가 생성되면 다음과 같이 FragmentStateAdapter로 부터 상속받을 수 있게 만들고

package com.example.myapplication

import androidx.viewpager2.adapter.FragmentStateAdapter

class FragmentAdapter: FragmentStateAdapter {
}

FragmentStateAdapter에서 Alt + Enter 키를 눌러 'Add Construcor..'중 FragmentActivity를 받는 항목을 선택합니다.

 

package com.example.myapplication

import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter

class FragmentAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) {
}

이번에는 FragmentAdapter에서 Alt + Enter키를 눌러 Implement members를 선택합니다.

 

목록에서 나오는 모든 메서드를 선택한 후 OK버튼을 누릅니다.

 

추가된 메서드는 2개로 getItemCount()는 전체 Fragment의 개수를, createFragment() 메서드는 현재 화면에 표시된 Fragment를 반환해야 합니다.

class FragmentAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) {
    override fun getItemCount(): Int {
        TODO("Not yet implemented")
    }

    override fun createFragment(position: Int): Fragment {
        TODO("Not yet implemented")
    }
}

메서드 안에 모든 TODO는 삭제하고 각각의 메서드에 필요한 내용을 구현합니다. 이를 위해 우선 모든 Fragment 담아두는 전체 fragmentList변수를 생성하여 getItemCount()에는 fragmentList의 갯수를, createFragment()에서는 현재 Fragment의 position값을 받아 position에 해당하는 Fragment를 반환하도록 합니다.

class FragmentAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) {
    var fragmentList = listOf<Fragment>()

    override fun getItemCount(): Int {
        return fragmentList.count()
    }

    override fun createFragment(position: Int): Fragment {
        return fragmentList.get(position)
    }
}

MainActivity에서는 조금전 만들어둔 실제 Fragment를 담는 변수를 생성하고

var fragmentList = listOf(MyFragment1(), MyFragment2(), MyFragment3())

필요한 adapter를 생성된뒤 adapter의 fragmentList에 위에서 생성한 fragmentList를 전달합니다. 그리고 이렇게 만들어진 adapter를 위에서 올려둔 myViewPager의 adapter로 다시 전달하면 됩니다.

package com.example.myapplication

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.fragment.app.FragmentPagerAdapter
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var fragmentList = listOf(MyFragment1(), MyFragment2(), MyFragment3())

        val adapter = FragmentAdapter(this)
        adapter.fragmentList = fragmentList
        myViewPager.adapter = adapter
    }
}

이제 앱을 실행시켜보면 좌우 스와이프동작에 따라 Fragment화면이 전환되는 것을 볼 수 있습니다.

 

필요하다면 setOrientation을 설정하는 것만으로 좌우가 아닌 상하방향으로도 화면이 전환될 수 있도록 구성할 수 있습니다.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var fragmentList = listOf(MyFragment1(), MyFragment2(), MyFragment3())

        val adapter = FragmentAdapter(this)
        adapter.fragmentList = fragmentList
        myViewPager.adapter = adapter

        myViewPager.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
    }
}

마지막으로 ViewPager2는 필요한 경우 TabLayout과 연동되는 경우가 많은데 TabLayout과 연동하는 경우를 간단히 말 펴보고 마칠까 합니다.

 

우선 아래와 같이 TabLayout을 적당한 곳에 배치합니다.

 

그리고 Adapter에서의 createFragment 메서드를 다음과 같이 수정합니다. 탭을 선택할때 지정한 Fragment를 반환하도록 합니다.

override fun createFragment(position: Int): Fragment {
    return when(position){
        0 -> MyFragment1()
        1 -> MyFragment2()
        else -> MyFragment3()
    }
}

이제 MainActivity의 onCreate에서 TabLayoutMediator를 이용해 추가한 TabLayout과 ViewPager2를 연결합니다. 예제에서는 TabLayout의 제목을 인덱스로 처리했지만 당연히 다른 필요한 내용으로 변경할 수 있습니다.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    var fragmentList = listOf(MyFragment1(), MyFragment2(), MyFragment3())

    val adapter = FragmentAdapter(this)
    adapter.fragmentList = fragmentList
    myViewPager.adapter = adapter

    TabLayoutMediator(myTabLayout, myViewPager){tab, position->
        tab.text = position.toString()
    }.attach()
}

728x90

'Mobile > Kotlin' 카테고리의 다른 글

[kotlin] 저장소및 파일처리  (0) 2020.12.24
[kotlin] 권한 처리하기  (0) 2020.12.23
[Kotlin] 위젯 - ViewPager2  (0) 2020.12.23
[Kotlin] Widget 만들기  (0) 2020.12.22
[Kotlin] View  (0) 2020.12.22
[Kotlin] Flagment  (0) 2020.12.21

관련글 더보기

댓글 영역