如何使用 Motion Layout 设置 ImageView 的位置 [英] How to set a position of ImageView using Motion Layout

查看:28
本文介绍了如何使用 Motion Layout 设置 ImageView 的位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如何将对象(例如图像视图)从起点移动到终点,

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆