展开/折叠工具栏拉动视图

时间:2019-07-03 10:47:17

标签: android android-layout android-coordinatorlayout

我正在尝试使用CollapsingToolbarLayout底部的AppBarLayout和其他视图创建以下行为,但是在{{1}上滚动/拉动时,栏未折叠/展开}},这意味着在折叠或使用视图关闭时无法打开栏。

我已经尝试在PullView根目录中使用NestedScrollView,但没有成功

PullView

enter image description here enter image description here

1 个答案:

答案 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

现在是最终结果:

Menu Example