Foggy day
Android(Kotlin) - FlexibleViewPagerHeight when you want to apply wrapContent to viewPager 본문
Android(Kotlin) - FlexibleViewPagerHeight when you want to apply wrapContent to viewPager
jinhan38 2020. 12. 26. 16:48
Normal viewpager does not have the wrapContent attribute applied. However, someTimes we need to set height of the ViewPager to match the contents. So I created a CustomViewPager class that extends ViewPager and The CustomViewPager allows you to flexibly set height of ChildViews.
To understand this post, you must have a basic understanding of ViewPager.
Video preview
1. CustomViewPager
First of all, make a CustomViewPager that extends 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
var height = 0
for (i in 0 until childCount) {
val child = getChildAt(i)
child.measure(
widthMeasureSpec,
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
)
val h = child.measuredHeight
if (h > height) height = h
}
if (height != 0) {
heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
}
2. Make 3 ViewPagerItems
The view height and backgroundColor of eash fragment was set diffrently.
1) FlexibleFragmentFirst
class FlexibleFragmentFirst : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_flexible_first, container, false)
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/brand_purple"
tools:context=".viewPager.flexibleHeight.FlexibleFragmentFirst">
<View
android:layout_width="match_parent"
android:layout_height="300dp"/>
</FrameLayout>
2) FlexibleFragmentSecond
class FlexibleFragmentSecond : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_flexible_second, container, false)
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/brand_green"
tools:context=".viewPager.flexibleHeight.FlexibleFragmentSecond">
<View
android:layout_width="match_parent"
android:layout_height="200dp"/>
</FrameLayout>
3) FlexibleFragmentThird
class FlexibleFragmentThird : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_flexible_third, container, false)
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/brand_blue"
tools:context=".viewPager.flexibleHeight.FlexibleFragmentThird">
<View
android:layout_width="match_parent"
android:layout_height="100dp" />
</FrameLayout>
3. Make a ViewPagerAdapter
class ViewPagerAdapter : FragmentPagerAdapter {
constructor(fm: FragmentManager) : super(fm)
private var fragmentArrayList = ArrayList<Fragment>()
override fun getCount(): Int {
return fragmentArrayList.size
}
override fun getItem(position: Int): Fragment {
return fragmentArrayList[position]
}
fun addItem(fragment: Fragment) {
this.fragmentArrayList.add(fragment)
}
}
4. Now, connect the fragments inside the viewpager.
1) activity_flexible_view_pager_height.xml
To distinguish it from the viewpager, I made the backgroundColor gray.
The package path name of CustomViewPager will be different depending on your package Name.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="@color/brand_gray"
android:orientation="vertical"
tools:context=".viewPager.flexibleHeight.FlexibleViewPagerHeightActivity">
<com.jinhanexample.viewPager.flexibleHeight.CustomViewPager
android:id="@+id/flexibleViewPager"
android:layout_width="match_parent"
android:layout_height="400dp" />
</LinearLayout>
2) FlexibleViewPagerHeightActivity
If you specify a int value for offscreenPageLimit, the height of the viewpager is set to the fragment with the largest height value. Because I set 300dp on FlexibleFragmentFirst, the height of my ViewPager is set to 300dp.
class FlexibleViewPagerHeightActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_flexible_view_pager_height)
val first = FlexibleFragmentFirst()
val second = FlexibleFragmentSecond()
val third = FlexibleFragmentThird()
flexibleViewPager.offscreenPageLimit = 3
val viewPagerAdapter = ViewPagerAdapter(supportFragmentManager)
viewPagerAdapter.addItem(first)
viewPagerAdapter.addItem(second)
viewPagerAdapter.addItem(third)
flexibleViewPager.adapter = viewPagerAdapter
}
}
'Android' 카테고리의 다른 글
Android(Java, kotlin) - Appbar Animation with ViewPager inside Fragment (0) | 2020.12.29 |
---|---|
Android Custom View: Extending The Views (0) | 2020.12.27 |
Android(kotlin) - custom circle progressBar (0) | 2020.12.27 |
Android - 최고의 커스텀 뷰 가이드 (0) | 2020.12.27 |
Android(Java) - composite design pattern example (0) | 2020.12.26 |