본문 바로가기
KUIT-앱 개발 프로젝트 동아리

5주차 실습(1)-Glide 라이브러리, ViewPager2

by 농농씨 2023. 10. 27.

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의 어댑터를 상속받음

: RecyclerView.Adapter<ImageSliderVPAdapter.ViewHolder>()

파라미터로 ImageSliderVPAdapter.ViewHolder넣어주는 이유는 ? 모르겠음?

일단 ViewHolder inner 클래스 만들어줌

일단 옆에 소괄호 붙여주는 것도 잊지 말아야함 constructor invocation 인것같지만 잘 모르겠음

 

recyclerView의 Adapter 상속받았기 때문에 3가지 메서드 override 해주고

 

6-1. inner class ViewHolder 구현

여기서의 binding은 뷰페이저이지만(?뭔말? 암튼 뷰페이저어댑터파일임)

어댑터는 결국 아이템이미지의 binding을 얻어와야 하기 때문에 ItemImageBinding 해주고 & ViewHolder 상속받음(왜인지모름)

inner class ViewHolder(val binding: ItemImageBinding) : RecyclerView.ViewHolder(binding.root)

이때 상속받는 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("냥냥냥")
    }
}

 

잘된다.

'KUIT-앱 개발 프로젝트 동아리' 카테고리의 다른 글

6주차 이론-Thread  (0) 2023.10.30
5주차 실습(2)-TabLayout  (0) 2023.10.27
4주차 실습 복습  (1) 2023.10.27
4주차 실습-RecyclerView  (0) 2023.10.04
3주차 미션-Bottom Navigation  (1) 2023.10.04