47

我有一个带有这个layoutDescription的运动布局:app:layoutDescription="@xml/scene"

场景.xml

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

    <Transition
        motion:constraintSetStart="@layout/view_home_card_start"
        motion:constraintSetEnd="@layout/view_home_card_end"
        motion:duration="1000">
        <OnSwipe
            motion:touchAnchorId="@+id/button"
            motion:touchAnchorSide="left"
            motion:dragDirection="dragLeft" />
    </Transition>

</MotionScene>

我认为view_home_card_startand的 xmlview_home_card_end是无关紧要的。

如何以编程方式调用此动画?

4

6 回答 6

60

最后我这样做:

((MotionLayout)findViewById(R.id.motionLayout)).transitionToEnd();
((MotionLayout)findViewById(R.id.motionLayout)).transitionToStart();
于 2018-09-24T07:29:37.770 回答
16

您也可以在您的 xml 中执行此操作

motion:autoTransition="animateToEnd"

motion:autoTransition="animateToStart"
于 2020-05-30T22:49:27.020 回答
7

如果有人从片段中执行此操作:

  1. 进口:

    import androidx.constraintlayout.motion.widget.MotionLayout;
    
  2. 实例化 MotionLayout:

    MotionLayout motionLayout = view.findViewById(R.id.your_motion_layout);
    
  3. 过渡到运动的结束/开始:

    motionLayout.transitionToStart();
    

或者

    motionLayout.transitionToEnd();
于 2020-06-10T06:13:30.527 回答
7

我们可以像这样简单地做 motion_layout.transitionToEnd()

但是在 Activity 恢复时,它会快速启动我们的动画,以至于我们可能会错过几个或整个动画。所以我建议增加一些延迟,比如。

GlobalScope.launch (Dispatchers.IO){
        delay(1000)
        withContext(Dispatchers.Main){
            motion_layout.transitionToEnd()
        }
    }

如果未添加,您还需要添加 Coroutines 依赖项。

实现 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'

于 2020-10-04T12:25:30.593 回答
2
In Latest Update of Constraint **2.0.0-beta1** Layout There are Public methods add in motion layout 
        you can get these methods with the help of motionlayout id 
    **motionLayout** 

     1. public void setProgress (float pos) 
     2. public void setTransition (int
           beginId,int endId)  
     3. public void setTransitionDuration (int
               milliseconds)  public void setTransitionListener
               (MotionLayout.TransitionListener listener)

     4. public void setState (int
               id,int screenWidth, 
                             int screenHeight)

     5. if(wantShowUi)
            {
                newUserActivityBinding.coordinatorLayout.transitionToStart();
            }
            else
            {
                newUserActivityBinding.coordinatorLayout.transitionToEnd();
            }

      <android.support.constraint.motion.MotionLayout
                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:id="@+id/motionLayout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layoutDescription="@xml/motion_scene_01"
                tools:showPaths="true">

            <View
                    android:id="@+id/button"
                    android:background="@color/colorAccent"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:soundEffectsEnabled="false"
                    tools:layout_editor_absoluteY="361dp"
                    tools:layout_editor_absoluteX="61dp"/>


        </android.support.constraint.motion.MotionLayout>
于 2019-05-13T11:40:11.557 回答
0

我正在使用transitionToState()方法在某些操作的状态之间进行转换。

fun navigateToPayment() {
    binding?.motionLayoutContainer?.transitionToState(R.id.statePayment)
}

fun navigateToShipping() {
    binding?.motionLayoutContainer?.transitionToState(R.id.stateShipping)
}

也使用相同的方法来处理 Activity 中的后按。

override fun onBackPressed() {
    binding?.motionLayoutContainer?.currentState?.let{
        when(it) {
            R.id.paymentState -> {
                //go back to shipping
                binding?.layoutSheet?.transitionToState(R.id.shippingState)
            }
            R.id.shippingState -> {
                //go back to cart
                binding?.layoutSheet?.transitionToState(R.id.cartState)
            }
            else -> {
                Toast.makeText(this, "Invalid Transition State", Toast.LENGTH_SHORT).show()
            }
        }
    } ?: run{
        //finish activity
        super.onBackPressed()
    }
}
于 2021-11-07T09:47:49.250 回答