제이슨의 개발이야기
ViewPager2 로 양쪽 페이지 살짝 보이게 만들기! 본문
안녕하세요 ! 오늘은 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
'안드로이드' 카테고리의 다른 글
Service 컴포넌트 onTaskRemoved(rootIntent: Intent?) 앱을 강제종료 시켰을 때 (0) | 2021.07.20 |
---|---|
안드로이드 서버 응답을 기다리는 중 화면터치 막는 방법 ! (0) | 2021.07.14 |
Firebase RemoteConfig 이용해보기! Android with Coroutin , viewPager2 이용 (1) | 2021.06.03 |
FCM 푸시메시지 보낼때 안드로이드 화면 깨우기 Kotlin (0) | 2021.05.28 |
Edit text 글자 입력 시 검색 페이지 개발 with 알고리아서치 API(Algoria Search Api) (0) | 2021.05.28 |