ViewPager2

쿵ㅇ양·2024년 1월 13일
0

Android

목록 보기
10/30

ViewPager2???

viewPager2 는 RecyclerView 를 상속받기 때문에 매우 유사함

사용법

1. 종속성 추가

implementation("androidx.viewpager2:viewpager2:1.0.0")

2. xml 파일에 뷰페이저2 추가

뷰페이저를 넣고 싶은 곳에 뷰페이저 추가해주기

<androidx.viewpager2.widget.ViewPager2
                android:id="@+id/mainProfile_vp"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                app:layout_constraintTop_toBottomOf="@id/profileStorage_search"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                android:clipToPadding="false"
                android:clipChildren="false">

            </androidx.viewpager2.widget.ViewPager2>

3. item.xml

나는 동일한 화면에 페이지마다 텍스트뷰와 이미지뷰만 바뀌는 것이기 때문에 뷰페이저에 들어갈 하나의 아이템을 만들어주었다.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
    <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:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/myprofile_bg"/>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <ImageView
                android:id="@+id/multiProfile_char_iv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/myprofile_character"
                android:layout_marginTop="120dp"
                android:layout_marginLeft="90dp" />

            <TextView
                android:id="@+id/multiProfile_Name_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="정서연"
                android:fontFamily="@font/gmarketsansmedium"
                android:textSize="25sp"
                android:layout_marginTop="50dp"
                android:layout_marginLeft="160dp"/>

            <TextView
                android:id="@+id/multiProfile_Number_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="010-1234-5678"
                android:fontFamily="@font/gmarketsansbold"
                android:textSize="15sp"
                android:layout_marginTop="30dp"
                android:layout_marginLeft="140dp"/>

        </LinearLayout>


        <ImageView
            android:layout_width="150dp"
            android:layout_height="100dp"
            android:src="@drawable/myprofile_logo"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_marginTop="530dp"
            app:layout_constraintLeft_toLeftOf="parent"
            android:layout_marginLeft="110dp"/>

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

4. 데이터 클래스 생성

페이지마다 변화를 줄 데이터인 이름과 프로필사진, 전화번호는 변수로 선언

data class MultiProfileData(
    val profileImageResId: Int,
    val name: String,
    val phoneNumber: String
)

5. 어댑터 설정

Adapter 는 아까 만들어놓은 틀 (화면) 에 데이터들을 차곡차곡 넣어주는 역할
내가 만든 화면의 경우,
1. ImageView 2. TextView1 3. TextView2
세 개의 위젯이 있는데 어떤 데이터를 이미지에 넣고, 어떤 데이터를 텍스트뷰에 넣을 건지 등을 정하는 부분

가장 먼저 이너클래스로 viewholder 정의하기!
multiprofile_item 의 위젯들과 인자로 전달한 데이터(위에 코드에선 item: multiprofile) 를 연결


//ListAdapter 상속받아 아이템 목록 관리/갱신
class MainProfileVPAdapter : ListAdapter<MultiProfileData, MainProfileVPAdapter.MainItemViewHolder>(MainListDiffCallback()) {

    // onCreateViewHolder: 뷰홀더 객체 생성 및 뷰홀더 레이아웃 설정
    //아이템을 뷰홀더에 연결하고 뷰홀더 생성해줌
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainItemViewHolder {
        
        //아이템xml을 뷰바인딩 객체 생성
        val binding = ItemMultiprofileBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        // 뷰홀더에 아이템 넣어 객체를 생성하고 반환
        return MainItemViewHolder(binding)
    }

    // onBindViewHolder: 뷰홀더에 데이터 바인딩
    //각 아이템의 위치(position)에 해당하는 데이터를 뷰홀더에 전달하여 표시
    //알맞는 위치에 데이터를 뿌려주는 역할
    override fun onBindViewHolder(holder: MainItemViewHolder, position: Int) {
        
        // 뷰홀더에 데이터를 바인딩하는 함수 호출
        holder.bind(getItem(position))
    }

    // MainItemViewHolder: 뷰홀더 클래스
    inner class MainItemViewHolder(private val binding: ItemMultiprofileBinding) : RecyclerView.ViewHolder(binding.root) {
        
        //bind: 데이터를 뷰에 바인딩하는 함수
        fun bind(item: MultiProfileData) {
            
            // 뷰바인딩을 통해 각 아이템의 데이터를 설정
            binding.multiProfileCharIv.setImageResource(item.profileImageResId)
            binding.multiProfileNameTv.text = item.name
            binding.multiProfileNumberTv.text = item.phoneNumber
        }
    }

    
    // MainListDiffCallback: 아이템 변경을 감지하는 콜백 클래스
    class MainListDiffCallback : DiffUtil.ItemCallback<MultiProfileData>() {
        
        // areItemsTheSame: 아이템이 같은지 여부를 판단
        override fun areItemsTheSame(oldItem: MultiProfileData, newItem: MultiProfileData): Boolean {
            
            // 아이템의 고유 식별자를 비교하여 같은 아이템인지 여부를 반환
            return oldItem == newItem
        }

        // areContentsTheSame: 아이템 내용이 같은지 여부를 판단
        override fun areContentsTheSame(oldItem: MultiProfileData, newItem: MultiProfileData): Boolean {
            
    // 아이템의 내용을 비교하여 같은 내용인지 여부를 반환 (예: 이름이 같은 경우 같은 내용으로 간주)
            return oldItem.name == newItem.name
        }
    }
}

6. MainProfileFragment.kt

프래그먼트와 어댑터 연결하고 리스트에 데이터 직접 넣어줌

class MainProfileFragment : Fragment() {

    // ViewBinding을 사용하여 레이아웃과 바인딩된 객체 연결
    lateinit var binding : FragmentMainprofileBinding
    
    //데이터 클래스의 데이터 담을 리스트 생성
    private val multiList = mutableListOf<MultiProfileData>()
    
    //ViewPager 어댑터 생성
    private val vpadapter = MainProfileVPAdapter()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        // ViewBinding을 통해 프래그먼트의 레이아웃과 연결된 바인딩 객체 초기화
        binding= FragmentMainprofileBinding.inflate(inflater,container,false)

        //하단의 함수 실행
        initViewPager()


        return binding.root
    }

    //ViewPager 초기화 함수
    private fun initViewPager(){
        val multiList = mutableListOf<MultiProfileData>()

        // 초기 프로필 데이터를 MutableList에 추가
        multiList.add(MultiProfileData(R.drawable.myprofile_character, "1", "010-1234-5678"))
        multiList.add(MultiProfileData(R.drawable.myprofile_character, "2", "010-1234-5678"))
        multiList.add(MultiProfileData(R.drawable.myprofile_character, "3", "010-1234-5678"))


        //어댑터 초기화
        val vpadapter = MainProfileVPAdapter()

        // 어댑터에 데이터 제출
        vpadapter.submitList(multiList)

        //xml의 뷰페이저에 어댑터 연결
        binding.mainProfileVp.adapter = vpadapter



    }



}
profile
개발을 공부하고 있는 대학생

0개의 댓글

관련 채용 정보