BottomNavigationViewの下までコンテンツが割り込んでしまう問題 (Contents overlapping)
2021/03/04
CoordinatorLayoutの中に、AppBarLayout、コンテンツのConstraintLayout、BottomNavigationView、を入れて、真ん中にコンテンツを配置したい場合。コンテンツにlayout_behaviorを設定するとAppBarはよけてくれますが、BottomNavigationは考慮してもらえません。
app:layout_behavior="@string/appbar_scrolling_view_behavior"
そこで、コンテンツの下にバーの高さ分のマージンが追加されるように、このクラスをカスタマイズします。
class AppBarWithBottomScrollingViewBehavior(context: Context, attrs: AttributeSet): AppBarLayout.ScrollingViewBehavior(context, attrs) {
override fun layoutDependsOn(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
return super.layoutDependsOn(parent, child, dependency) || dependency is BottomAppBar || dependency is BottomNavigationView
}
override fun onDependentViewChanged(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
super.onDependentViewChanged(parent, child, dependency)
if (dependency is BottomAppBar || dependency is BottomNavigationView) {
(child.layoutParams as? CoordinatorLayout.LayoutParams)?.let {
if (it.bottomMargin != dependency.height) {
it.bottomMargin = dependency.height
child.requestLayout()
return true
}
}
}
return false
}
}
自動的にマージンが追加されるので、レイアウト側でandroid:layout_marginは設定しないようにします。
このクラスを使ってもらえるようにstringsに設定します。
<string name="appbar_scrolling_view_behavior" translatable="false">com.example.myapplication.ui.main.AppBarWithBottomScrollingViewBehavior</string>
クラスはフルパスで指定しないとRuntimeExceptionでクラッシュしてしまいます。
java.lang.RuntimeException: Unable to start activity ComponentInfo: android.view.InflateException: Binary XML file in activity: Could not inflate Behavior subclass com.example.myapplication.debug.ui.main.AppBarWithBottomScrollingViewBehavior
これでバーの間にコンテンツが綺麗に挟まります。
このクラスは、コンテンツ部分がフラグメントの場合、BottomNavigationをBottomAppBarに入れて使う場合、のいずれも確認済みです。