제이슨의 개발이야기

ViewPager2 로 양쪽 페이지 살짝 보이게 만들기! 본문

안드로이드

ViewPager2 로 양쪽 페이지 살짝 보이게 만들기!

제이쓰은 2021. 6. 4. 16:22
728x90
반응형

안녕하세요 ! 오늘은 ViewPager2 에 대해서 공부해봤습니다 그리고 좀 더 응용해서 양쪽 페이지가 살짝 보이게 만들어봤습니다! 

 

사실 ViewPager 에 대한 내용을 예전에 블로그에 작성한적 있습니다 

 

그때는 ViewPager 이였고 요번에는 ViewPager2 입니다

 

ViewPager2는 기존 ViewPager 와 크게 달라젔습니다 

 

일단 가장 큰 차이는 ViewPager2 는 RecyclerView 를 이용한다는 점입니다! RecyclerView 를 이용하면서 

기존보다 메모리 리소스도 줄일 수 있는 장점이 있어 앞으로 개발을 하게 된다면 ViewPager2 를 이용하는것을 추천합니다! 

 

물론 ViewPager2의 단점도 있습니다 ViewPager 에 비해 나온지 얼마안되서 개발 중 여러 버그가 존재한다고 하더라구요 

그래서 일부 개발자들은 여전히 ViewPager 를 그대로 사용하는 경우도 있다고 합니다

 

그러나 시간이 더 지나면 분명 RecyclerView를 이용하는 ViewPager2를 더 많이 사용할 것으로 저는 예상하고있습니다! 

activity.xml

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#323131"
    tools:context=".MainActivity">
<androidx.viewpager2.widget.ViewPager2
    android:layout_width="match_parent"
    android:layout_height="500dp"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:id="@+id/viewpager2"
        android:clipChildren="false"
        android:clipToPadding="false"
    android:paddingStart="30dp"
    android:paddingEnd="30dp"
    android:paddingTop="30dp"
    android:paddingBottom="30dp"
    android:orientation="horizontal"
    android:layout_marginTop="20dp"/>

<LinearLayout
    android:layout_width="0dp"
    android:id="@+id/indicators"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toBottomOf="@id/viewpager2"

    android:padding="15dp"
    android:layout_marginStart="20dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>

activity_main.xml 코드에서 

viewPager2 태그 안에

android:clipChildren="false"
android:clipToPadding="false"

부분이 있습니다 양쪽에 사진을 살짝 보이게 하려면 필수적으로 clipChildren 과 clipToPadding 을 false 로 바꿔줘야합니다! 

 

viewPager2Adapter

class ViewPager2Adater(var list : ArrayList<Int>,var context : Context)  : RecyclerView.Adapter<RecyclerView.ViewHolder>(){
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {

        var view = LayoutInflater.from(parent.context).inflate(R.layout.item,parent,false)
        return viewHolder(view)

    }

    override fun getItemCount(): Int {
        return list.size
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        (holder as viewHolder).image.setBackgroundColor(list.get(position))
    }

    inner class viewHolder(var view : View) : RecyclerView.ViewHolder(view){
            var image : ImageView  = view.findViewById(R.id.image)
    }
}

앞서 설명한 대로 viewPager2는 RecyclerView를 이용하기 때문에 기존에 RecyclerView를 아시는 분들에게는 전혀 새롭지 않은 코드 입니다! 

 

 

MainActivity.kt

 

class MainActivity : AppCompatActivity() {

    var layoutOnBoardingIndicators : LinearLayout ?=null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var list = ArrayList<Int>()

        list.add(Color.parseColor("#ffff00"))
        list.add(Color.parseColor("#bdbdbd"))
        list.add(Color.parseColor("#0f9231"))
        var adater = ViewPager2Adater(list,applicationContext)

        var viewpager = findViewById<ViewPager2>(R.id.viewpager2)
        viewpager.offscreenPageLimit=3
        viewpager.getChildAt(0).overScrollMode=View.OVER_SCROLL_NEVER
        viewpager.adapter = adater


        layoutOnBoardingIndicators = findViewById(R.id.indicators)
        setupOnBoardingIndicators()
        setCurrentOnboardingIndicator(0)

                var transform = CompositePageTransformer()
        transform.addTransformer(MarginPageTransformer(8))

        transform.addTransformer(ViewPager2.PageTransformer{ view: View, fl: Float ->
            var v = 1-Math.abs(fl)
            view.scaleY = 0.8f + v * 0.2f
        })

        viewpager.setPageTransformer(transform)


        viewpager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback(){
            override fun onPageSelected(position : Int){
                setCurrentOnboardingIndicator(position)
            }

        })
    }

    private fun setupOnBoardingIndicators(){
        val indicators =
            arrayOfNulls<ImageView>(3)

        var layoutParams = LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT
        )

        layoutParams.setMargins(8,0,8,0)

        for( i in indicators.indices){
            indicators[i] = ImageView(applicationContext)
            indicators[i]?.setImageDrawable(ContextCompat.getDrawable(
                applicationContext,
                R.drawable.onboarding_indicator_inactivie
            ))

            indicators[i]?.layoutParams = layoutParams

            layoutOnBoardingIndicators?.addView(indicators[i])
        }
    }

    private fun setCurrentOnboardingIndicator( index : Int){
        var childCount = layoutOnBoardingIndicators?.childCount
        for(i in  0 until childCount!!){
            var imageView = layoutOnBoardingIndicators?.getChildAt(i) as ImageView
            if(i==index){
                imageView.setImageDrawable(ContextCompat.getDrawable(applicationContext,
                    R.drawable.onboarding_indicator_active))
            }else{
                imageView.setImageDrawable(ContextCompat.getDrawable(applicationContext,
                    R.drawable.onboarding_indicator_inactivie))
            }
        }
    }
}

MainActivity.kt 에서는 

 

viewpager.offscreenPageLimit=3  이 코드가 있어야 양 옆에 이미지가 나타납니다! 

그리고

transform.addTransformer(ViewPager2.PageTransformer{ view: View, fl: Float ->
var v = 1-Math.abs(fl)
view.scaleY = 0.8f + v * 0.2f
}

이 부분은 양 옆에 사진의 사이즈를 줄여서 현재 사진이 앞으로 튀어 나와있는거 같은 효과를 주는 부분입니다! 

위 4줄 코드를 지우면 양 옆에 사진은 똑같아 집니다

 

나머지 인디케이터 의 대한 설명은 생략하겠습니다

 

사실 요번 인디케이터 코드 역시 저번에 구현했던 텝 레이아웃을 이용한 방식이 아닌 각각의 이미지 뷰를 만들어서 부여하는 방식으로 구현했습니다 텝 레이아웃을 이용해서 구현 하는 것보다 커스텀 하기 쉬운거같아서 좋았지만 단점으로는 보이는 것처럼 코드가 길어지는 단점이 있는거같습니다 

인디케이터 부분이 궁금하시는 분들은 아래에 링크 클릭해주세요! 저는 유튜브를 통해서 배웠습니다

유튜브 뿐만 아니라 해당 프로젝트 전체 코드가 있는 깃헙링크도 아래에 올립니다!

https://github.com/jaeilssss/AndroidStudy/tree/main/viewPager2Project

 

jaeilssss/AndroidStudy

안드로이드 간단 공부 프로젝트 모음. Contribute to jaeilssss/AndroidStudy development by creating an account on GitHub.

github.com

 

https://youtu.be/hraJ8iT8pn0

 

 

 

728x90
반응형