无法对 Motionlayout 中的两个不同元素执行两个操作 | Android 工作室

Can't manage to preform two actions on two different elements in Motionlayout | Android Studio

我有一个运动布局,可以在覆盖它下面的元素和向上滑动时显示它之间来回移动,这个元素(仪表板)上面有一个向上滑动的图像,让用户知道它是可滑动。这里的问题是我希望“向上滑动箭头”在滑动后消失。

但我遇到了几个问题:动画布局无法识别其下方元素以外的元素,因此动画布局似乎无法对多个元素进行转换。

所以我想我会以编程方式进行。每当向上滑动仪表板(黑色的)元素时,向上滑动图像将设置为不可见,但在开始设置后,仪表板元素现在会忽略运动布局中的向上滑动侦听器并确认 kotlin 侦听器。

作为一个新的android开发者,我只能想到几个解决方案。其中之一是以编程方式向仪表板添加向上滑动侦听器,并使用它向上转换并使箭头消失,或者找到一种方法使运动布局向上转换仪表板并在滑动后删除向上滑动图像

这两个我都不会做,我也愿意接受更有效的替代方法

How it looks before its been swiped

How it should look after

主要activity:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="500dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <androidx.cardview.widget.CardView
            android:id="@+id/dashboard"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:cardBackgroundColor="@color/green"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

        </androidx.cardview.widget.CardView>
    </androidx.constraintlayout.widget.ConstraintLayout>

    <androidx.constraintlayout.motion.widget.MotionLayout
        android:id="@+id/constraintLayout12"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:elevation="20dp"
        app:layoutDescription="@xml/activity_main_light_copy_2_xml_constraintlayout12_scene"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <ImageView
            android:id="@+id/swipeUpPic"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            app:layout_constraintBottom_toBottomOf="@id/dashboard"
            app:layout_constraintEnd_toEndOf="@id/dashboard"
            app:layout_constraintStart_toStartOf="@id/dashboard"
            app:srcCompat="@drawable/scroll_image" />
    </androidx.constraintlayout.motion.widget.MotionLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

动作布局:

<?xml version="1.0" encoding="utf-8"?>
<MotionScene 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">

    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="1000">

        <OnSwipe
            motion:touchAnchorId="@id/dashboard"
            motion:dragDirection="dragUp"
            motion:touchAnchorSide="top" />

    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@id/dashboard"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent" >
        </Constraint>

        <Constraint
            android:id="@id/swipeUpPic"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="visible"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent" >
        </Constraint>

    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@id/dashboard"
            android:layout_width="match_parent"
            android:layout_height="400dp"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent" >
        </Constraint>

        <Constraint
            android:id="@id/swipeUpPic"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            android:visibility="invisible">
        </Constraint>
    </ConstraintSet>
</MotionScene>

有几种方法可以实现。

  1. 扁平化设计(不要嵌套视图)
  2. 嵌套 MotionLayout
  3. 构建自定义 ViewGroup(按照您尝试执行的操作)

最简单的就是简单的扁平化设计。弄清楚如何制作虚拟面板有点棘手。 MotionLayout 中视图的顺序是 z 顺序(底部优先)。玩弄它你可以解决它。 出于 team/architecture 原因,您可能不想这样做。例如一个面板正在多个屏幕上被取消。

2 和 3 只是彼此的变体。 这个想法是 ViewGroup 子类监听 setProgress(float x) 并且控制 motionLayout 在正确的点调用 setProgress。

MotionLayout 已经侦听 setProgress,所以其中一些已经为您完成。

关键是外部 MotionLayout 面板在滑动控制中。

我还建议您看几个例子: https://developer.android.com/training/constraint-layout/motionlayout/examples

首先让我说,我完全同意@hoford。

最好的方法是将 MotionLayout 展平,但是您可以 show/hide 通过添加 TransitionListener to your MotionLayout. Use addTransitionListener()

向上滑动按钮

您可以使用:

  • onTransitionStarted() Called when a drawer is about to start a transition. Note. startId may be -1 if starting from an "undefined state". The startId and endId refers to the ConstraintSet ids.
  • onTransitionChange() Called when a drawer's position changes. Where you can even track the current (transition) progress and apply the same transition state to your own View(s).