ViewPager에서 ViewPager2 사용법 변경 (코틀린/Kotlin)

2022. 7. 13. 13:38프로그램/안드로이드

안드로이드 생존코딩을 공부하고 있습니다.

8장 전자액자 부분을 보면 사진들이 좌우로 슬라이드 되는 기능이 있는데

ViewPager를 사용하며 Glide 라이브러리를 이용합니다.

 

그런데 ViewPager가 deprecated되었다고 안드로이드 스튜디오에서 나오네요

저자에게 메일로 문의를 했는데 아래와 같이 답장을 주셨습니다.

 

안녕하세요.
해당 클래스가 deprecated 되어서 ViewPager2 를 사용해야 하네요.
다음 블로그가 도움이 되실 듯 합니다.
감사합니다.

 

일단은 ViewPager 원리가 어떻게 되는지 살펴보기 위해 검색을 했는데

https://ju-hy.tistory.com/55

 

ViewPager 사용법

ViewPager란? ViewPager는 좌우 스크롤을 통해 화면을 넘겨볼 수 있는 기능을 제공해준다. 부분 화면 여러 개를 변환하여 보여주기 때문에 Fragment를 사용하여 구현하며, 여러 개 중 하나를 선택하는 형

ju-hy.tistory.com

위 페이지가 설명이 잘 되어있었습니다. (자바로 구현)

코틀린도 원리는 비슷한거같습니다.

 

1. ViewPager 안에 들어갈 Fragment 만들기

2. 메인 xml에 ViewPager를 추가

3. 클래스를 만든다. FragmentStatePagerAdapter 상속 (더이상 안씀)

4. MainActivity에서 전환될 부분화면 Fragment를 넘겨받아 addItem()이용하여 arrayList에 넣어준다

5. ViewPager에 adapter를 지정하면 된다.

 

부스트코스에서 참고하였다고 씌여있네요 (무료강의)

https://www.edwith.org/boostcourse-android

 

부스트코스 소개 : 부스트코스

부스트코스는 혼자일 때보다 더 쉽게 더 많은 것을 배울 수 있는 공간, 선배 개발자가 재능을 나누고 더 많은 이와의 소통을 경험할 수 있는 커뮤니티를 만들어가고자 합니다. 이를 위해 2020년 12

www.boostcourse.org

 

 

ViewPager2 사용법은 아래의 사이트에서 실마리를 찾았습니다.

https://tutorialwing.com/viewpager2-with-fragment-and-fragmentstateadapter/

 

ViewPager2 With Fragment and FragmentStateAdapter - Tutorialwing

Learn viewpager2 with fragment and fragmentstateadapter with example, learn to use FragmentStateAdapter in viewPager2 with adapter

tutorialwing.com

옆에 메뉴 보니까 여러 강좌가 많이 있어서 도움이 될거같네요.

 

수정된 코드

 

* MainActivity

 

package com.example.mygallery

import android.Manifest
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.widget.ViewPager2
import org.jetbrains.anko.*

@Suppress("DEPRECATION")
class MainActivity : AppCompatActivity() {

private val REQUEST_READ_EXTERNAL_STORAGE = 1000

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

// 권한이 부여되었는지 확인
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

// 권한이 허용되지 않음 (전에 권한요청 거부했는지 반환)
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
// 이전에 이미 권한이 거부되었을 때 설명
alert("사진 정보를 얻으려면 외부 저장소 권한이 필수로 필요합니다", "권한이 필요한 이유") {
yesButton {
// 권한 요청
ActivityCompat.requestPermissions(this@MainActivity,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
REQUEST_READ_EXTERNAL_STORAGE)
}
noButton {}
}.show()
} else {
// 권한 요청
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
REQUEST_READ_EXTERNAL_STORAGE)
}

} else {
// 권한이 이미 허용됨
getAllPhotos()
}

}

private fun getAllPhotos() {
// 모든 사진 정보 가져오기
val cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null,
null,
null,
MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC")

val fragments = ArrayList()

if (cursor != null) {
while (cursor.moveToNext()) {
// 사진 경로 Uri 가져오기
val uri = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA))
Log.d("MainActivity", uri)
fragments.add(PhotoFragment.newInstance(uri))
}
cursor.close()
}

// 어댑터 fragmentActivity: FragmentActivity
// https://tutorialwing.com/viewpager2-with-fragment-and-fragmentstateadapter/
    val adapter = MyPagerAdapter(this) //------------------------------------------
    adapter.updateFragments(fragments)
    val viewPager = findViewById(R.id.viewPager)
    viewPager.adapter = adapter
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
REQUEST_READ_EXTERNAL_STORAGE -> {
if ((grantResults.isNotEmpty()
&& grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
// 권한 허용됨
getAllPhotos()
} else {
// 권한 거부
toast("권한 거부 됨")
}
return
}
}
}

}

 

* MyPagerAdapter

 

package com.example.mygallery

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

// https://srandroid.tistory.com/211
// https://furang-note.tistory.com/26 FragmentStateAdapter 소개함
// FragmentStatePagerAdapter deprecated
// https://stackoverflow.com/questions/56778106/fragmentpageradapter-deprecated

//class MyPagerAdapter(fragment: FragmentManager) : FragmentStateAdapter(fragment) {
class MyPagerAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) {

    private val items = ArrayList()

    // 아이템 개수
    override fun getItemCount(): Int {
        return items.size
    }

 

    // position 위치의 프래그먼트
    override fun createFragment(position: Int): Fragment {
        return items[position]
    }

 

    fun addFragment(fragment: Fragment) {
        items.add(fragment)
        notifyItemInserted(items.size-1)
    }

 

    fun removeFragment() {
        items.removeLast()
        notifyItemRemoved(items.size)
    }

 

    // 아이템 갱신
    fun updateFragments(items: List) {
        this.items.addAll(items)
    }

}

 

 

* PhotoFragment.kt

 

package com.example.mygallery

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import com.bumptech.glide.Glide

private const val ARG_URI = "uri"

class PhotoFragment : Fragment() {

private var uri: String? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
uri = it.getString(ARG_URI)

}
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_photo, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val imageView = view.findViewById(R.id.imageView)
Glide.with(this).load(uri).into(imageView)
}

companion object {
@JvmStatic
fun newInstance(uri: String) =
PhotoFragment().apply {
arguments = Bundle().apply {
putString(ARG_URI, uri)
}
}
}
}

 

 

* activity_main.xml의 ViewPager는 ViewPager2로 변경

<androidx.viewpager2.widget.ViewPager2 ... 로 사용