缩放过渡动画

时间:2018-01-24 19:56:31

标签: android android-layout animation android-animation android-constraintlayout

我想为ConstraintLayout中的Scale View元素创建自定义Transition。在AutoTransition.java内。我们有Fade In,AdjustBounds和Fade Out。因此,执行简单的缩放并不会对更改进行动画处理。

经过一些解决方法后,我能够使用Scale创建自定义过渡。我的观点是,创建具有Visiblity和Scale的过渡集。尽管存在Scale Pivot,但在下面的更改中,此动画效果很好。

 //..................... General method from Custom Scale Transition


@Nullable
@Override
public Animator createAnimator(@NonNull ViewGroup sceneRoot, @Nullable TransitionValues startValues,
                               @Nullable TransitionValues endValues) {
    if (null == startValues || null == endValues) {
        return null;
    }
    final View view = endValues.view;
    final float startX = (float) startValues.values.get(PROPNAME_SCALE_X);
    final float endX = (float) endValues.values.get(PROPNAME_SCALE_X);


    final float startY = (float) startValues.values.get(PROPNAME_SCALE_Y);
    final float endY = (float) endValues.values.get(PROPNAME_SCALE_Y);

    final AnimatorSet set = new AnimatorSet();
    final ValueAnimator animatorX = ValueAnimator.ofFloat(startX, endX);
    animatorX.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            final float value = (float) animation.getAnimatedValue();
            view.setScaleX(value);
        }
    });

    final ValueAnimator animatorY = ValueAnimator.ofFloat(startY, endY);
    animatorY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            final float value = (float) animation.getAnimatedValue();
            view.setScaleY(value);
        }
    });

    set.playTogether(animatorX, animatorY);
    return set;
}


 //..................... Complete Set Transitions


public class ScaleVisibility extends TransitionSet {

    public ScaleVisibility() {
        setOrdering(ORDERING_TOGETHER);
        addTransition(new Fade()).
                addTransition(new Scale());
    }
}

 //..................... Code for starting Animation. 

    mConstraintSet.clone(mConstraintLayout);
    Transition transition = new ScaleVisibility();
    transition.setDuration(3000);

    mConstraintSet.setScaleX(item.resource, item.scale);
    mConstraintSet.setScaleY(item.resource, item.scale);
    mConstraintSet.setTransformPivot(item.resource, 0.5f, 0.5f);
    mConstraintSet.setVisibility(item.resource, item.visibility);

    TransitionManager.beginDelayedTransition(mConstraintLayout, transition);
    mConstraintSet.applyTo(mConstraintLayout);


 //..................... Main XML. Trying to Animate input_send_button

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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/fragment_input_panel"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <View
        android:id="@+id/input_background"
        android:layout_width="match_parent"
        android:layout_height="@dimen/chat_input_panel_height"
        android:background="@color/white"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <!--This View will change Visibility with Text Changes-->
    <ImageButton
        android:id="@+id/input_send_button"
        android:layout_width="@dimen/chat_input_panel_height"
        android:layout_height="0dp"
        android:background="@android:color/transparent"
        android:src="@drawable/chat_send"
        android:tint="@color/primary"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="@+id/input_background"
        app:layout_constraintRight_toRightOf="@+id/input_background"
        app:layout_constraintTop_toTopOf="@+id/input_background"
        tools:ignore="ContentDescription"
        tools:visibility="visible"/>

</android.support.constraint.ConstraintLayout>

这里的主要问题是它的Scale动画Pivot,它为零(视图的左上角)。我无法更改动画视图的Transition枢轴。将此属性添加到View.javaConstraintSet.java参数均无效。因此,如何更改View Pivot以进行此规模转换。 (作为补充问题,我有兴趣更改Pivot的默认AdjustBounds Transition,我们更改视图高度/宽度)。

2 个答案:

答案 0 :(得分:3)

尝试在每个动画步骤中重置枢轴。如果您正在寻找中心枢轴,则可以斜切getWidth(),否则您需要捕获另一个枢轴值并使用它。

尝试这种转变:

public class ScaleTransition extends Transition {
    private final static String PROPNAME_SCALE_X = "PROPNAME_SCALE_X";
    private final static String PROPNAME_SCALE_Y = "PROPNAME_SCALE_Y";

    @Override
    public void captureStartValues(TransitionValues transitionValues) {
        captureValues(transitionValues);
    }

    @Override
    public void captureEndValues(TransitionValues transitionValues) {
        captureValues(transitionValues);
    }

    private void captureValues(TransitionValues values){
        values.values.put(PROPNAME_SCALE_X, values.view.getScaleX());
        values.values.put(PROPNAME_SCALE_Y, values.view.getScaleY());
    }

    @Override
    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
        if(endValues == null || startValues == null)
            return null;    // no values

        float startX = (float) startValues.values.get(PROPNAME_SCALE_X);
        float startY = (float) startValues.values.get(PROPNAME_SCALE_Y);
        float endX = (float) endValues.values.get(PROPNAME_SCALE_X);
        float endY = (float) endValues.values.get(PROPNAME_SCALE_Y);

        if(startX == endX && startY == endY)
            return null;    // no scale to run

        final View view = startValues.view;
        PropertyValuesHolder propX = PropertyValuesHolder.ofFloat(PROPNAME_SCALE_X, startX, endX);
        PropertyValuesHolder propY = PropertyValuesHolder.ofFloat(PROPNAME_SCALE_Y, startY, endY);
        ValueAnimator valAnim = ValueAnimator.ofPropertyValuesHolder(propX, propY);
        valAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                view.setPivotX(view.getWidth()/2f);
                view.setPivotY(view.getHeight()/2f);
                view.setScaleX((float) valueAnimator.getAnimatedValue(PROPNAME_SCALE_X));
                view.setScaleY((float) valueAnimator.getAnimatedValue(PROPNAME_SCALE_Y));
            }
        });
        return valAnim;
    }
}

答案 1 :(得分:1)

要为TransitionManager创建自定义转换,您需要创建自定义TransitionTransitionSet。例如:

TransitionSet transitionSet = new TransitionSet();

//your types of transitions
Transition first = new ChangeBounds();
Transition second = new Fade();

first.addTarget(firstView);
second.addTarget(secondView);

//Add your transitions to TransitionSet
transitionSet.addTransition(first).addTransition(second);

//Start transitions
TransitionManager.beginDelayedTransition(layout, transitionSet);

您可以详细了解TransitionSet hereTransition here