Search code examples
androidandroid-layoutandroid-animationandroid-constraintlayout

Slide animation when guideline percent changes


I have a view that looks like this:

https://i.sstatic.net/zKe01.png

When clicked, I want to animate the grey background color so that it slides from the right side to 50% of its initial width:

https://i.sstatic.net/s96BX.png

Here is the relevant portion of the layout xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/content_view"
    android:layout_width="match_parent"
    android:layout_height="44dp"
    android:layout_marginBottom="4dp">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="1.0"/>

    <View
        android:id="@+id/background"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="@+id/guideline"
        android:background="@drawable/background" />

</androidx.constraintlayout.widget.ConstraintLayout>

I've tried the following:

contentView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ConstraintSet constraintSet = new ConstraintSet();
        constraintSet.clone(contentView);
        constraintSet.setGuidelinePercent(guideline.getId(), 0.5f);

        TransitionManager.beginDelayedTransition(contentView);
        constraintSet.applyTo(contentView);
    }
});

But instead of the background color sliding from the right to the left (100% to 50%), it sort of just cross-fades.

What am I doing wrong? How would I change my code so the animation SLIDES the background color when the guideline percent changes?


Solution

  • You can use android.animation.ValueAnimator to change the percentage value of your guideline inside your constraintLayout, the code would be like this:

    contentView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // initialize your guideline
                    // Guideline guideline = findViewById ....
                    
                    ValueAnimator valueAnimator = ValueAnimator.ofFloat(1.0f, 0.5f);
                    
                    // set duration
                    valueAnimator.setDuration(1000);
                    // set interpolator and  updateListener to get the animated value
                    valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
                    
                    // update guideline percent value through LayoutParams
                    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                        @Override
                        public void onAnimationUpdate(ValueAnimator animation) {
                            ConstraintLayout.LayoutParams lp = (ConstraintLayout.LayoutParams) guideline.getLayoutParams();
                            // get the float value
                            lp.guidePercent = (Float) animation.getAnimatedValue();
                            // update layout params
                            guideline.setLayoutParams(lp);
                        }
    
                    });
                    valueAnimator.start();
    
                }
            });