5주차 실습(1)-Glide 라이브러리, ViewPager2
1. 그래들 뷰바인딩 설정
2. 그래들 glide 라이브러리 사용설정 복붙
3. AndroidManifest에서
<uses-permission android:name="android.permission.INTERNET"/>
인터넷 사용설정 해줘야 glide 라이브러리 쓸수있음
4. 메인액티비티에서 viewPager2랑 텍스트뷰 넣기
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.viewpager2.widget.ViewPager2
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="@id/text_area_cl"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/text_area_cl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent" >
<TextView
android:id="@+id/text_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="개"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
5. 이미지 넣을 레이아웃 만들기
item_image.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/item_iv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
</androidx.constraintlayout.widget.ConstraintLayout>
전에는 리소스파일에 이미지 넣고 R.drawable.id 이런식으로 불러왔었는데 glide 라이브러리로 이미지를 불러와보겠음
메인액티비티에서 glide 라이브러리 설정하고 데이터 받아오기 전에,
어댑터 설정을 먼저 해주도록 하겠음
6. 뷰페이저 어댑터 구현
액티비티 생성
ImageSliderVPAdapter
이때 glide를 사용하기 위해서는 VPAdapter가, 뷰페이저가 있는 Activity나 Fragment의 context를 인자로 받아와서 생성자로 넣어줘야 함.
Url의 데이터타입은 String으로 전달할 예정.
ImageSliderVPAdapter는 RecyclerView의 어댑터를 상속받음
파라미터로 ImageSliderVPAdapter.ViewHolder넣어주는 이유는 ? 모르겠음?
일단 ViewHolder inner 클래스 만들어줌
일단 옆에 소괄호 붙여주는 것도 잊지 말아야함 constructor invocation 인것같지만 잘 모르겠음
recyclerView의 Adapter 상속받았기 때문에 3가지 메서드 override 해주고
6-1. inner class ViewHolder 구현
여기서의 binding은 뷰페이저이지만(?뭔말? 암튼 뷰페이저어댑터파일임)
어댑터는 결국 아이템이미지의 binding을 얻어와야 하기 때문에 ItemImageBinding 해주고 & ViewHolder 상속받음(왜인지모름)
이때 상속받는 ViewHolder에 뷰가 들어가야 하는데 binding.root 가 뷰 객체로 들어감
fun bind() 구현은 (스크롤할때마다 실행되는 onBindViewHolder의 코드를 간소화하기 위한 함수였음)
이미지 리스트 안에 들어있는 이미지 url을 glide를 통해 받아와서 이미지뷰에 출력해줄 예정
-.with(context): context 넣어주고
-.load(imgUrl): img url 넣어주고
-.into(binding.itemIv): 이미지뷰 안에, 받아온 이미지 url을 넣음
추가로 .placeholder나 .error같은 메서드 넣어줄수도 있음
6-2. override fun onCreateViewHolder 구현
뷰홀더 생성될 때 호출되는 메서드
아이템 이미지 바인딩을 inflate 해주고
아이템뷰(의 바인딩)을 가진 ViewHolder 를 리턴함.
6-3. override fun getItemCount
그냥 아이템 사이즈 리턴
6-4. override fun onBindViewHolder
스크롤해서 새로운 뷰홀더 객체를 재사용할때마다 뷰홀더 안에 있는 데이터를 변경하기 위해 호출됨
아까 ViewHolder에 선언해준 bind 함수를 호출함
imgList에 있는 데이터를 glide를 이용해서 position 써서 이미지 출력함
// ImageSliderVPAdapter.kt 전체코드
package com.iyr.viewpager2practice
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.iyr.viewpager2practice.databinding.ItemImageBinding
class ImageSliderVPAdapter(val context: Context, val imgList : MutableList<String>) : RecyclerView.Adapter<ImageSliderVPAdapter.ViewHolder>() {
inner class ViewHolder(val binding: ItemImageBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(imgUrl: String){
Glide.with(context)
.load(imgUrl)
.into(binding.itemIv)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemImageBinding.inflate(LayoutInflater.from(parent.context),parent,false)
return ViewHolder(binding)
}
override fun getItemCount(): Int = imgList.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(imgList[position])
}
}
메인액티비티에서 사용하는 방법은 recyclerView와 차이가 있음(뭐가 다르지?)
7. MainActivity 구성
뷰바인딩 먼저 해주고
데이터 담을 자료구조(이미지리스트, 텍스트 리스트) 선언
7-1. onCreate
바인딩&inflate 해주고
setContentView(binding.root)
dummy 데이터 함수도 넣어줌
initDummyData()
7-2. private fun initDummyData()
pixabay 라는 사이트 참고
imgList.add("url 정보")
textList.add("텍스트")
7-3. private fun initViewPager()
onCreate에 먼저 initViewPager() 넣어준다음
그 밖에 함수 선언해주고
binding.imageAreaVp.Adapter = ImageSliderVPAdapter(applicationContext, imgList)
바인딩한 뷰페이저의 어댑터에 내가 만든 어댑터 넣어줌.
이때 생성자에 context랑 list 전달해주기로 했으므로 넣어줌
그 외에 필요한 설정 여러가지
binding.imageAreaVp.orientation = ViewPager2.ORIENTATION_HORIZONTAL
스와이프 방향(기본은 가로)
// 여기까지 이미지뷰 세팅
스와이프 할때 텍스트뷰 세팅
이어서 mainActivity의 fun initViewPager 안에서
setTextViewChangeEvent() 이런 이벤트를 설정하는 함수를 쓰고 함수는 밖에 선언해줄 예정
7-4. private fun setTextViewChangeEvent()
binding.imageAreaVp.registerOnPageChangeCallback
// 뷰페이저의 여러 속성 중 하나.
cf. 콜백함수 추가 공부
: 어떤 이벤트가 발생했을 때 감지해서 알려주고, 다른 행동 하도록 하는 함수
내용은 인터페이스로 구현함 마치 리사이클러뷰 어댑터에 인터페이스 만들었던 것처럼...
인자로는 콜백함수 넣어줘야 함.
binding.imageAreaVp.registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback(){
// 익명함수
override fun onPageSelected(position: Int) {
// 페이지 선택됐을 때
binding.textTv.text = textList[position]
// 바인딩한 텍스트뷰를 텍스트리스트의 position 값으로 세팅해줌
}
})
// MainActivity 전체 코드
package com.iyr.viewpager2practice
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.viewpager2.widget.ViewPager2
import com.iyr.viewpager2practice.databinding.ActivityMainBinding
class MainActivity : ComponentActivity() {
private lateinit var binding : ActivityMainBinding
private val imgList = mutableListOf<String>()
private val textList = mutableListOf<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initDummyData()
initViewPager()
}
private fun initViewPager() {
binding.imageAreaVp.adapter = ImageSliderVPAdapter(applicationContext, imgList)
binding.imageAreaVp.orientation = ViewPager2.ORIENTATION_HORIZONTAL
setTextViewChangeEvent()
}
private fun setTextViewChangeEvent() {
binding.imageAreaVp.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback(){
override fun onPageSelected(position: Int) {
binding.textTv.text = textList[position]
}
})
}
private fun initDummyData() {
imgList.add("https://cdn.pixabay.com/photo/2014/11/30/14/11/cat-551554_1280.jpg")
imgList.add("https://cdn.pixabay.com/photo/2014/04/13/20/49/cat-323262_1280.jpg")
imgList.add("https://cdn.pixabay.com/photo/2017/07/25/01/22/cat-2536662_1280.jpg")
textList.add("냥")
textList.add("냥냥")
textList.add("냥냥냥")
}
}
잘된다.