AppBarLayout перекрывает пользовательский макет с моим пользовательским поведением - PullRequest
0 голосов
/ 12 ноября 2018

Я знаю, что в 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
}
...