滑动时减慢motionLayout动画

时间:2019-09-26 19:40:55

标签: android android-motionlayout

我有motionLayout的{​​{1}}动画:

transition

但是动画对我来说太快了。我想放慢脚步。我尝试设置<Transition app:constraintSetEnd="@+id/end" app:constraintSetStart="@+id/start"> <OnSwipe app:dragDirection="dragUp" app:dragScale="0.1" app:touchAnchorId="@id/my_scrollview" /> </Transition> ,但它不会影响动画速度。 我如何放慢速度?

3 个答案:

答案 0 :(得分:0)

根据Android Developer documentation,Transition类具有一个可以在XML文件中设置的属性,名为char。通过指定过渡应该运行的时间(以毫秒为单位)来尝试使用它。

答案 1 :(得分:0)

我最终从我的MotionScene中删除了<OnSwipe>,并使用了MotionLayout的Transition侦听器和RecyclerView的Scroll侦听器来检查滚动方向并触发相应的过渡。

创建一些成员变量以跟踪过渡状态:

    private boolean mTransitioningToEnd = false;
    private boolean mTransitioningToStart = false;

然后,在您的Activity / Fragment的onCreate()中:

    int endState = motionLayout.getEndState();
    int startState = motionLayout.getStartState();

    motionLayout.setTransitionListener(new MotionLayout.TransitionListener() {
        @Override
        public void onTransitionStarted(MotionLayout motionLayout, int startId, int endId) {
        }

        @Override
        public void onTransitionChange(MotionLayout motionLayout, int startId, int endId, float progress) {
        }

        @Override
        public void onTransitionCompleted(MotionLayout motionLayout, int currentId) {
            // Update transition variables when completed
            if(currentId == startState){
                mTransitioningToStart = false;
            }else if(currentId == endState){
                mTransitioningToEnd = false;
            }
        }

        @Override
        public void onTransitionTrigger(MotionLayout motionLayout, int triggerId, boolean positive, float progress) {
        }
    });

    myRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            int currentState = motionLayout.getCurrentState();
            int threshold = 25; // Use a threshold to compare significant scroll motion

            // Check for significant vertical motion
            // and that we're not already transitioning
            if(dy > threshold && currentState != endState && !mTransitioningToEnd){
                motionLayout.transitionToEnd();

                // Track the transition
                mTransitioningToEnd = true;
                mTransitioningToStart = false;
            }else if(dy < -threshold && currentState != startState && !mTransitioningToStart){
                motionLayout.transitionToStart();

                // Track the transition
                mTransitioningToStart = true;
                mTransitioningToEnd = false;
            }


            super.onScrolled(recyclerView, dx, dy);
        }
    });
    

这不一定是理想的方法。它将以MotionScene中设置的持续时间在任一方向上播放完整的过渡。但是它并不直接与滚动量相对应,因此,如果您正在寻找部分进度,它不会中途停止过渡。

答案 2 :(得分:0)

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

    <OnSwipe 
        motion:touchAnchorId="@id/view"
        motion:dragDirection="dragDown"
        motion:maxVelocity="20"
        motion:maxAcceleration="20"/>
 </Transition>

简短答案::修改持续时间,touchAnchorId,maxVelocity,maxAcceleration。 提高速度和加速度并降低持续时间

好答案

通常,滑动动画分为两个阶段 当手指触摸“拖动阶段”而不是“拖动阶段”时

  1. 拖动阶段 拖动阶段动画将跟踪您的手指。 如果未设置touchAnchorId,则在整个屏幕上拖动将使您从头到尾。 如果设置touchAnchorId,则拖动将与您选择的视图的速度匹配。视图移动距离的阻力将带您从头到尾。
  2. 归档阶段 拖动开始的速度设置为拖动阶段结束时的速度。目标将成为持续时间内的开始或结束。加速或减速到最大速度。

因此,对于上面的示例,如果您拖动到中间并向上拖动鼠标,它将尝试使您在一秒内到达终点,然后以20(DDp / s2)的速度最大加速到20(Dp / ds)惯性滑行,直到时间恰到好处,以至于20时减速,最后停止。

将其视为汽车的最高速度是最高速度。 maxAcceleration是0-60时间。 持续时间就是您要到达那里的时间。

dragScale 是在“拖动阶段”中计算出的拖动进度的倍数

我正在简化许多其他细节,但这已经变得很复杂。