gpt4 book ai didi

android - 拉动 View 的展开/折叠工具栏

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:10:16 27 4
gpt4 key购买 nike

我正在尝试使用 CollapsingToolbarLayoutAppBarLayout 底部的其他 View 来创建以下行为,但是当我滚动时栏没有折叠/展开/拉动 PullView,这意味着在使用 View 折叠或关闭时无法打开栏。

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

<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">

<FrameLayout
android:id="@+id/frmContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:expanded="true">

<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

<FrameLayout
android:id="@+id/frmMenu"
android:layout_width="match_parent"
android:layout_height="300dp"
android:clickable="true"
android:focusable="true"/>

</com.google.android.material.appbar.CollapsingToolbarLayout>

</com.google.android.material.appbar.AppBarLayout>

<com.xpto.customview.PullView
android:id="@+id/pullDownView"
android:layout_width="50dp"
android:layout_height="wrap_content"
app:layout_anchor="@+id/appBarLayout"
app:layout_anchorGravity="bottom|center_horizontal"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>


</androidx.coordinatorlayout.widget.CoordinatorLayout>

</FrameLayout>

enter image description here enter image description here

最佳答案

我使用 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菜单

<?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

<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">

<ConstraintSet android:id="@+id/start">
<Constraint android:id="@id/menu">
<Layout
android:layout_width="0dp"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toTopOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent" />
</Constraint>

<Constraint android:id="@id/menuIndicator">
<Layout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toBottomOf="@id/menu" />
</Constraint>

</ConstraintSet>

<ConstraintSet
android:id="@+id/end"
motion:deriveConstraintsFrom="@id/start">
<Constraint android:id="@id/menu">
<Layout
android:layout_width="0dp"
android:layout_height="wrap_content"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
</Constraint>

<Constraint android:id="@id/menuIndicator">
<Layout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="@id/menu"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent" />
</Constraint>

</ConstraintSet>

<!-- All the animations values are hardcoded for now. -->
<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="400">

<OnSwipe
motion:dragDirection="dragDown"
motion:dragScale="0.5"
motion:maxAcceleration="10"
motion:maxVelocity="10.0" />

</Transition>

</MotionScene>

现在是最终结果:

Menu Example

关于android - 拉动 View 的展开/折叠工具栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56868393/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com