Я знаю, что в SO много вопросов о перекрытии.Но в моем случае я не могу понять, как изменить поведение, чтобы удалить наложение и сделать прокрутку текста.
В документах Google говорится, что мы должны добавить «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: 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
}