我知道有很多关于SO重叠的问题。但以我为例,我不明白如何更改行为以删除重叠部分并使文本滚动。
Google的文档说,我们必须为coordinatorLayout的所有子项添加“ app:layout_behavior”,如果我添加了
layout_behavior="@string/appbar_scrolling_view_behavior"
重叠被删除,但是如何使用我的自定义行为来估计重叠。我调试了onMeasureChild和onLayoutChild方法,并且每次使用自定义行为时都看到appBarLayout的高度等于0。
CoordinatorLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|snap">
<include layout="@layout/fragment_userinfo" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
<LinearLayout
android:id="@+id/navigation_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/colorPrimary"/>
</com.google.android.material.appbar.AppBarLayout>
<com.navigation.NavigationLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:layout_gravity="bottom"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/text"/>
</com.navigation.NavigationLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
NavigationLayout
class NavigationLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null,
defStyleAttr: Int = 0): FrameLayout(context, attrs, defStyleAttr),
CoordinatorLayout.AttachedBehavior {
override fun getBehavior(): CoordinatorLayout.Behavior<NavigationLayout> {
return NavigationBehavior()
}
private val recyclerView: RecyclerView?
private val progressBar: ProgressBar? = null
init {
val a = context.obtainStyledAttributes(attrs, R.styleable.NavigationLayout,defStyleAttr,0)
val behavior = a.getBoolean(R.styleable.NavigationLayout_nav_layout_behavior, false)
removeAllViews()
a.recycle()
}
}
我使用NavigationBehavior中的下一个代码解决了这个问题。我有与在XML app中使用时相同的行为:layout_behavior =“ @ string / appbar_scrolling_view_behavior
class NavigationBehavior(context: Context, attrs: AttributeSet) : CoordinatorLayout.Behavior<NavigationLayout>(context, attrs) {
override fun layoutDependsOn(parent: CoordinatorLayout, child: NavigationLayout, dependency: View): Boolean {
return dependency is AppBarLayout
}
override fun onDependentViewChanged(parent: CoordinatorLayout, child: NavigationLayout, dependency: View): Boolean {
child.top = dependency.measuredHeight + dependency.y.toInt()
val childParams = child.layoutParams
childParams.height = child.bottom - child.top
child.layoutParams = childParams
return true
}
override fun onLayoutChild(parent: CoordinatorLayout, child: NavigationLayout, layoutDirection: Int): Boolean {
return super.onLayoutChild(parent, child, layoutDirection)
}
override fun onMeasureChild(parent: CoordinatorLayout, child: NavigationLayout, parentWidthMeasureSpec: Int, widthUsed: Int,
parentHeightMeasureSpec: Int, heightUsed: Int): Boolean {
val appBarLayout = findFirstAppBarLayout(parent.getDependencies(child))
if (appBarLayout != null) {
val availableHeight = View.MeasureSpec.getSize(parentHeightMeasureSpec) - appBarLayout.measuredHeight
val newParentHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(availableHeight, View.MeasureSpec.AT_MOST)
parent.onMeasureChild(child, parentWidthMeasureSpec, widthUsed, newParentHeightMeasureSpec, heightUsed)
return true
} else {
return super.onMeasureChild(parent, child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed)
}
}
private fun findFirstAppBarLayout(views: List<View>): AppBarLayout? =
views.firstOrNull { view -> view is AppBarLayout } as? AppBarLayout
}