我正在尝试使用CollapsingToolbarLayout
底部的AppBarLayout
和其他视图创建以下行为,但是在{{1}上滚动/拉动时,栏未折叠/展开}},这意味着在折叠或使用视图关闭时无法打开栏。
我已经尝试在PullView
根目录中使用NestedScrollView
,但没有成功
PullView
答案 0 :(得分:2)
我发现使用MotionLayout
可以解决问题。
首先,我要扩展MotionLayout
来改变其行为,而不是拖动整个MotionLayout
,我只希望可以在指示器和菜单上拖动。
TLDR: Example on Github
因此,我的MotionLayout
将覆盖OnTouchEvent
,并检查我们是否接触了其中一个直属孩子。
class TouchableMotionLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0)
: MotionLayout(context, attrs, defStyleAttr), MotionLayout.TransitionListener {
private val viewRect = Rect()
private var touchStarted = false
init {
initListener()
}
private fun initListener() {
setTransitionListener(this)
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.actionMasked) {
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
touchStarted = false
return super.onTouchEvent(event)
}
}
if (!touchStarted) {
touchStarted = verifyIfChildHasTouched(event)
}
return touchStarted && super.onTouchEvent(event)
}
/**
* Verify if touching one fo the children.
*
* @param event The motion event.
* @return True if touch its in one of the children.
*/
private fun verifyIfChildHasTouched(event: MotionEvent): Boolean {
for (index in 0 until childCount) {
val view = getChildAt(index)
view.getHitRect(viewRect)
if (viewRect.contains(event.x.toInt(), event.y.toInt())) {
return true
}
}
return false
}
override fun onTransitionCompleted(p0: MotionLayout?, p1: Int) {
touchStarted = false
}
override fun allowsTransition(p0: MotionScene.Transition?) = true
override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {}
override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int) {}
override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {}
}
在这种布局中,我有一个viewpager和一个自定义MotionLayout
,只能打开/关闭在MotionLayout
的直接子元素(即menuIndicator
和{{ 1}}。
menu
现在场景:<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager.widget.ViewPager
android:id="@+id/baseViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.extmkv.example.TouchableMotionLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/menu_scene">
<FrameLayout
android:id="@+id/menuIndicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:paddingBottom="8dp"
android:paddingEnd="16dp"
android:paddingStart="16dp"
android:paddingTop="48dp"
android:translationZ="1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/menu">
<FrameLayout
android:layout_width="@dimen/menu_indicator_outside_width"
android:layout_height="@dimen/menu_indicator_outside_height"
android:layout_gravity="center"
android:background="#F00"
tools:ignore="UselessParent" />
</FrameLayout>
<LinearLayout
android:id="@+id/menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|top"
android:background="#FFF"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<LinearLayout
android:id="@+id/lnrMenuOptionsContainer"
android:layout_width="match_parent"
android:layout_height="300dp"
android:orientation="horizontal" />
</LinearLayout>
</com.extmkv.example.TouchableMotionLayout>
</FrameLayout>
您可以调整拖动并最后更改@xml/menu_scene.xml
。
attrs
现在是最终结果: