안드로이드

[Android/Kotlin]ViewPager에 wrap_content 가능케 하기

mingmaeng 2020. 7. 6. 17:35

ConstraintsLayout을 사용할 때 뷰의 크기는 match_parent, wrap_content, 0dp로 크기를 조정하는게 일반적이다.

이 때 ScrollView안에 ViewPager가 들어가게 되면 제대로 화면에 보여주지 않을 때가 있다.

고정 dp를 주게 되면 잘 보이지만 이는 ConstraintLayout을 사용하는 의미가 퇴색된다.

그렇다고 wrap_content를 사용하려고 하자니 wrap_content는 제대로 작동하지 않는다.

 

그럴 때 우리는 어떻게 해야 ConstraintLayout의 장점을 살리면서 wrap_content 뿐 아니라 

ViewPager의 ScrollView 이슈를 해결 할 수 있을까?

 

방법은 다음과 같다.

 

다음과 같은 클래스를 하나 만들어 준다.

해당 클래스는 ViewPager를 상속 받은 클래스다.

 

import android.content.Context
import android.util.AttributeSet
import androidx.viewpager.widget.ViewPager

class CustomViewPager : ViewPager {
    constructor(context: Context?) : super(context!!) {}
    constructor(context: Context?, attrs: AttributeSet?) : super(
        context!!,
        attrs
    ) {}

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        var heightMeasureSpec = heightMeasureSpec

        val mode = MeasureSpec.getMode(heightMeasureSpec)

        if (mode == MeasureSpec.UNSPECIFIED || mode == MeasureSpec.AT_MOST) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
            var height = 0
            for (i in 0 until childCount) {
                val child = getChildAt(i)
                child.measure(
                    widthMeasureSpec,
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
                )
                val h = child.measuredHeight
                if (h > height) height = h
            }

            heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }
}

 

이제 xml 코드에서 ViewPager가 아닌 위에서 만들어 준 클래스를 사용하면 된다.

 

<...CustomViewPager
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ... />

 

간단한 클래스 생성만 하면 기존 ViewPager의 특성을 그대로 사용하면서 유동적인 크기를 보장할 수 있게 된다.