2022. 7. 13. 13:38ㆍ프로그램/안드로이드
안드로이드 생존코딩을 공부하고 있습니다.
8장 전자액자 부분을 보면 사진들이 좌우로 슬라이드 되는 기능이 있는데
ViewPager를 사용하며 Glide 라이브러리를 이용합니다.
그런데 ViewPager가 deprecated되었다고 안드로이드 스튜디오에서 나오네요
저자에게 메일로 문의를 했는데 아래와 같이 답장을 주셨습니다.
일단은 ViewPager 원리가 어떻게 되는지 살펴보기 위해 검색을 했는데
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 ... 로 사용
'프로그램 > 안드로이드' 카테고리의 다른 글
코틀린 위젯 만들기 (Kotlin Widget) (0) | 2024.02.27 |
---|---|
코틀린 에러 메세지 Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: (0) | 2023.11.01 |
코틀린 공식 홈페이지 (0) | 2022.07.13 |
Unresolved reference: java 오류 해결방법 (0) | 2022.06.23 |
[코틀린 5] 페이지 코드 설명 3 (MainActivity) (0) | 2020.02.03 |