Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scale transition animation

I want to create custom Transition for the Scale View elements in the ConstraintLayout. Inside the AutoTransition.java. We have Fade In, AdjustBounds and Fade Out. So performing simple Scale doesn't animate changes.

After some workaround I was able to Create custom Transition with Scale. And my point, it's to create Transition Set with Visiblity and Scale. With changes below this animation works well, despite 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>

Main issue here, it's Scale animation Pivot, which is zero (top left corner of view). And I cannot change Transition pivot for Animated view. Neither with adding this property to the View.java nor ConstraintSet.javaparameters. So question it's how to change View Pivot for this Scale Transition. (As additional question, I was interested with changing Pivot for the default AdjustBounds Transition, where we changing view Height/Width).

like image 243
GensaGames Avatar asked Apr 06 '26 14:04

GensaGames


2 Answers

Try resetting the pivot on each animation step. If you're looking for center pivot you can just slash through getWidth(), otherwise you need to capture another pivot value and use it.

Try this transition:

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;
    }
}
like image 90
Pawel Avatar answered Apr 09 '26 05:04

Pawel


In order to create a custom transition(s) for TransitionManager you need to create a custom Transition or TransitionSet. For example:

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

You can learn more about TransitionSet here and about Transition here

like image 28
Patryk Goworowski Avatar answered Apr 09 '26 05:04

Patryk Goworowski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!