【问题标题】:Scale transition animation缩放过渡动画
【发布时间】:2018-01-24 19:56:30
【问题描述】:

我想为 ConstraintLayout 中的缩放视图元素创建自定义转换。在AutoTransition.java 内。我们有淡入、调整边界和淡出。因此,执行简单的 Scale 不会为更改设置动画。

经过一些变通方法后,我能够使用 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>

这里的主要问题是缩放动画枢轴,它为零(视图左上角)。而且我无法更改动画视图的过渡轴。既不将此属性添加到View.java 也不添加ConstraintSet.java 参数。所以问题是如何改变这个比例转换的视图枢轴。 (作为附加问题,我对更改默认 AdjustBounds 过渡的 Pivot 感兴趣,我们在其中更改视图高度/宽度)。

【问题讨论】:

  • 请添加您的xml代码
  • @RamiJemli 已更新。
  • 你能解释一下什么是“这个视图会随着文本的变化而改变可见性”吗?如果你想让视图变成 GONE 而不是 INVISIBLE,这有点棘手。

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


【解决方案1】:

尝试在每个动画步骤上重置枢轴。如果您正在寻找中心枢轴,您可以通过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;
    }
}

【讨论】:

  • 如此简单且有效的解决方案。我错过了从大小设置枢轴,并假设使用百分比。谢谢!
【解决方案2】:

要为TransitionManager 创建自定义过渡,您需要创建自定义Transition 或TransitionSet。例如:

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);

您可以了解更多关于TransitionSethere和Transitionhere的信息

【讨论】:

  • 感谢您的信息。我将尝试使用 ConstraintLayout 来执行它。你有执行比例转换的样本吗?
  • 所以它不起作用。该转换不适用于约束。这里的问题是关于改变约束动画。
  • 你选择了什么方法?您是否添加了所有应设置动画的过渡及其目标(视图)?
  • 我没有找到适用于约束布局缩放的示例创建自定义转换。
猜你喜欢
  • 2018-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
相关资源
最近更新 更多