如何使用 Motion Layout 设置 ImageView 的位置 [英] How to set a position of ImageView using Motion Layout
问题描述
我知道如何将对象(例如图像视图)从起点移动到终点,
I know how to moving object (imageview, for example) to end from start point,
((MotionLayout)findViewById(R.id.motionLayout)).transitionToEnd();
但是如何将对象移动到 keyPosition
,当我点击一个按钮时?
but how move object to keyPosition
, when i clicked a button?
如果不可能,我必须使用哪些工具来做到这一点?
And if its impossible, which tools i must use, to do this?
运动布局代码:
motion_06_keyframe.xml
<androidx.constraintlayout.motion.widget.MotionLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/motionLayout"
app:layoutDescription="@xml/scene_06"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/button"
android:background="@color/colorAccent"
android:layout_width="64dp"
android:layout_height="64dp" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="36dp"
android:text="Button"
android:onClick="lol"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.47"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.motion.widget.MotionLayout>
scene_06.xml
<MotionScene
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetStart="@+id/start"
motion:constraintSetEnd="@+id/end"
motion:duration="1000"
motion:motionInterpolator="linear">
<OnSwipe
motion:touchAnchorId="@+id/button"
motion:touchAnchorSide="right"
motion:dragDirection="dragRight" />
<KeyFrameSet>
<KeyPosition
motion:keyPositionType="pathRelative"
motion:percentY="-0.25"
motion:framePosition="50"
motion:motionTarget="@id/button"/>
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="BackgroundColor"
motion:customColorValue="#D81B60"/>
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="BackgroundColor"
motion:customColorValue="#9999FF"/>
</Constraint>
</ConstraintSet>
</MotionScene>
推荐答案
KeyPosition
定义了动画应该经历的状态,你无法使用默认工具停止过渡.最好的选择是将您的过渡分为两部分:
KeyPosition
defines the state the animation should go through, u can't stop the transition there with default tools.
The best choice is to divide your transition into two:
1) 从中间开始
2) 中到尾
1) start to middle
2) middle to end
但问题是,如果当前状态是中间状态,MotionLayout
将不知道您想要转换到哪里.它采用 xml 文件中的第一个转换,因此您必须手动更改它才能执行第二个转换.
But the thing is, MotionLayout
won't know where you want to transition to if the current state is middle. It takes the first transition in the xml file, so you will have to change it manually to perform the second transition.
View button; // the button
boolean weWantTransitionToEnd; // depends on your logic, you can throw it away
MotionLayout motionLayout; // the layout
button.setOnClickListener(view -> {
switch (motionLayout.getCurrentState()) {
case R.id.start:
motionLayout.transitionToEnd();
break;
case R.id.middle:
if (weWantTransitionToEnd) {
motionLayout.setTransition(R.id.middle, R.id.end);
motionLayout.transitionToEnd();
} else {
motionLayout.setTransition(R.id.start, R.id.middle);
motionLayout.transitionToStart();
}
break;
case R.id.end:
motionLayout.transitionToStart();
break;
}
});
尽管如此,用户将无法正确刷卡.如果您希望用户能够在两个方向上滑动它并且在某些情况下这个方块停留在中间,您将不得不扩展 MotionLayout
类,只留下一个过渡(从开始到结束)) 并在其中实现您自己的逻辑.
The user won't be able to swipe this correctly though.
If you want the user to be able to swipe it in both directions and this square to stick in the middle in some cases, you will have to extend MotionLayout
class, leave only one transition (from start to end) and implement your own logic in it.
该键将覆盖 OnTouchEvent(MotionEvent event)
和 dispatchTouchEvent(MotionEvent event)
方法.
The key would be overriding OnTouchEvent(MotionEvent event)
and dispatchTouchEvent(MotionEvent event)
methods.
private boolean isThumbDown;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
isThumbDown = true;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
isThumbDown = false;
break;
}
return super.dispatchTouchEvent(ev);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
if (getProgress() > 0.47f && getProgress() < 0.53f && !isThumbDown) return false;
return super.onTouchEvent(event);
}
这样过渡可以在中间的 47% 到 53% 之间的某个位置停止,并且用户将能够继续向两个方向滑动.
That way the transition could stop somewhere in between 47% and 53% in the middle and the user would be able to continue swiping in both directions.
这篇关于如何使用 Motion Layout 设置 ImageView 的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!