Android – appbarlayout combines my custom view with layout_ Behavior overlap
I have a custom header whose custom behavior interacts with the coordinator layout. This header depends on the appbarlayout that contains collapsingtoolbarlayout and toolbars. When the toolbar layout is collapsed, the custom title adjusts its properties and locates in the way I want, but the second I reach the minimum height of the layout. Appbarlayout overlaps the custom title, I can't see it until I start expanding it
This is the code for the layout:
<?xml version="1.0" encoding="utf-8"?><android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="@dimen/mk_appbar_height">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_collapse"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="@dimen/mt_toolbar_height"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:titleEnabled="false">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
style="@style/ToolbarStyle"
android:layout_width="match_parent"
android:layout_height="@dimen/mt_toolbar_height"
app:layout_collapseMode="pin"
/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<!-- This is a layout intended for containing MonkeyChatFragment and/or MonkeyConversationsFragment
RelativeLayout has an issue that doesn't render the RecyclerView with the whole size of its
container linear layout.
The only viable solution is FrameLayout -->
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<FrameLayout
android:id="@+id/viewStatus"
android:layout_width="match_parent"
android:layout_height="@dimen/status_height"
android:layout_marginTop="@dimen/status_inverse_height"
android:background="@color/mk_status_connected"/>
<com.criptext.monkeykitui.toolbar.HeaderView
android:id="@+id/custom_toolbar"
layout="@layout/custom_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="56dp"
app:layout_behavior="com.criptext.monkeykitui.toolbar.HeaderViewBehavior"
app:behavior_overlapTop="64dp"
/></android.support.design.widget.CoordinatorLayout>
This is layout_ Code of behavior:
class HeaderViewBehavior(context: Context, attrs: AttributeSet? = null) : CoordinatorLayout.Behavior<HeaderView>(context, attrs){
private val MIN_AVATAR_PERCENTAGE_SIZE = 0.3f
private val EXTRA_FINAL_AVATAR_PADDING = 80
private val TAG = "behavior"
private val mContext: Context = context
private val mCustomFinalHeight: Float = 0.toFloat()
private var mStartToolbarPosition: Float = 0.toFloat()
private var mStartYPosition: Int = 0
private var mFinalYPosition: Int = 0
private var mStartHeight: Int = 0
private var mfontSize: Float = 20.toFloat()
private var mChangeBehaviorPoint: Float = 0.toFloat()
override fun layoutDependsOn(parent: CoordinatorLayout?, child: HeaderView?, dependency: View?): Boolean {
var hello = (dependency is AppBarLayout)
return hello
}
override fun onDependentViewChanged(parent: CoordinatorLayout, child: HeaderView, dependency: View): Boolean {
maybeInitProperties(child, dependency)
val maxScrollDistance = - mContext.resources.getDimension(R.dimen.mk_header_scroll)
val expandedPercentageFactor = dependency.y / maxScrollDistance
Log.d("TEST", dependency.y.toString())
Log.d("TEST", maxScrollDistance.toString())
if (expandedPercentageFactor < mChangeBehaviorPoint) {
val heightFactor = (mChangeBehaviorPoint - expandedPercentageFactor) / mChangeBehaviorPoint
val distanceYToSubtract = (mStartYPosition - mFinalYPosition) * (1f - expandedPercentageFactor) + child.getHeight() / 2
child.setY(mStartYPosition - distanceYToSubtract)
val heightToSubtract = (mStartHeight - mCustomFinalHeight) * heightFactor
val lp = child.layoutParams as CoordinatorLayout.LayoutParams
child.layoutParams = lp
} else {
val distanceYToSubtract = (mStartYPosition - mFinalYPosition) * (1f - expandedPercentageFactor)
child.setY(mStartYPosition - distanceYToSubtract)
if(mStartYPosition - distanceYToSubtract < mStartYPosition){
child.setY(mStartYPosition.toFloat())
}else if(mStartYPosition - distanceYToSubtract > mFinalYPosition){
child.setY(mFinalYPosition.toFloat())
}
child.title.textSize = mfontSize - (mfontSize - 25) * (1f - expandedPercentageFactor)
child.subtitle.textSize = 15 - (15 - 20) * (1f - expandedPercentageFactor)
child.imageView.layoutParams.height = (126 - (126 - 226) * (1f - expandedPercentageFactor)).toInt()
child.imageView.layoutParams.width = (126 - (126 - 226) * (1f - expandedPercentageFactor)).toInt()
}
return true
}
private fun maybeInitProperties(child: HeaderView, dependency: View) {
if (mStartYPosition === 0)
mStartYPosition = 0
if (mFinalYPosition === 0)
mFinalYPosition = mContext.resources.getDimension(R.dimen.mk_header_scroll).toInt()
if (mStartHeight === 0)
mStartHeight = child.getHeight()
if (mStartToolbarPosition === 0.toFloat())
mStartToolbarPosition = dependency.y
if (mChangeBehaviorPoint === 0.toFloat())
mChangeBehaviorPoint = (child.height - mCustomFinalHeight) / (2f * (mStartYPosition - mFinalYPosition))
}
}
resolvent:
Just in case others are looking for the same answer, I can say that I have found a solution in another so problem. It is useless to try various solutions after wasting 6 hours
In order for the view to visually override appbarlayout after folding, you need to add the Android: elevation = "8dp" (or higher) attribute to the overridden view
Therefore, the code part of the problem that needs to be changed is:
<com.criptext.monkeykitui.toolbar.HeaderView
android:id="@+id/custom_toolbar"
layout="@layout/custom_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="56dp"
app:layout_behavior="com.criptext.monkeykitui.toolbar.HeaderViewBehavior"
app:behavior_overlapTop="64dp"
/>
To:
<com.criptext.monkeykitui.toolbar.HeaderView
android:id="@+id/custom_toolbar"
layout="@layout/custom_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="56dp"
app:layout_behavior="com.criptext.monkeykitui.toolbar.HeaderViewBehavior"
app:behavior_overlapTop="64dp"
android:elevation="8dp"
/>
All credits are in @ Kris Larson's answer: coordinatorlayout custom behavior with appbarlayout