Skip to main content

CoordinatorLayoutの中のViewPager2の中にあるFragmentの中でボトムに固定したViewを作る

ボトムにフッター的なものを固定したいときあるよね
これがCoordinatorLayoutだと下にちょっと隠れて辛い
これの解消方法


・前提
Activityのレイアウト
このViewPager2の中のFragmentにbottomで固定したViewを作りたい

<androidx.coordinatorlayout.widget.CoordinatorLayout>
    <com.google.android.material.appbar.AppBarLayout>
        <androidx.appcompat.widget.Toolbar />
    </com.google.android.material.appbar.AppBarLayout>
    <androidx.viewpager2.widget.ViewPager2 app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

・やりかた
behaviorを拡張する
これする頭全然なかった

    <androidx.viewpager2.widget.ViewPager2 app:layout_behavior="パッケージ名.FixScrollingFooterBehavior" />

layoutDependsOnで監視する対象を指定
今回動くのはAppbarLayoutなので指定
onDependentViewChangedで対象が変更になったときに何するか記載
appBarの動く範囲と高さからpaddingいくつあてるか指定
これでFragmentに動的にpaddingがつくので一番下にViewを固定できましたとさ

class FixScrollingFooterBehavior : ScrollingViewBehavior {
    constructor() : super() {}
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {}


    override fun layoutDependsOn(
        parent: CoordinatorLayout,
        child: View,
        dependency: View
    ): Boolean {
        return dependency is AppBarLayout
    }

    override fun onDependentViewChanged(
        parent: CoordinatorLayout,
        child: View,
        dependency: View
    ): Boolean {
        val appBarLayout = dependency as AppBarLayout
        val result = super.onDependentViewChanged(parent, child, dependency)
        val bottomPadding = calculateBottomPadding(appBarLayout)
        val paddingChanged = bottomPadding != child.paddingBottom
        if (paddingChanged) {
            child.setPadding(
                child.paddingLeft,
                child.paddingTop,
                child.paddingRight,
                bottomPadding
            )
            child.requestLayout()
        }
        return paddingChanged || result
    }

    private fun calculateBottomPadding(dependency: AppBarLayout): Int {
        val totalScrollRange = dependency.totalScrollRange
        return totalScrollRange + dependency.top
    }
}

 

参考
https://stackoverflow.com/questions/37493215/fixed-view-in-viewpagers-content-layout-under-coordinatorlayout
https://techblog.yahoo.co.jp/android/androidcoordinatorlayout/

関連記事:

Pocket