Android - When scale animations wouldn't change height and width

   One might assume that Android's animation especially the ones based on property animation APIs (since 11) would actually change the view properties. A scale animation gives a feel that a view's height and width is actually changed. However, the view APIs like getWidth() and getHeight() would still return the old unchanged values. So how exactly is the view shown after scale and how does it respond to touch events? Would the scaled section of the view accept input events? Well, it depends on the layout. A simple layout with just one view might seem to work but the problem can be seen with a layout having multiple views.

    In this case, a linear layout has two image views in vertical orientation. Clicking the first image causes it to scale out. View.setScaleX and View.setScaleY doesn't actually change the width and height of the view and hence it doesn't alter the location of the second image view in the layout. Due to this, clicks on the section of the second image (overlapping the scaled view) is actually handled by the second image view and not the scaled image view.

 

Ok, now what if we want the view's actual height and width to be changed along with the scale animations like in this video?




   It can be done by not using the scale animation instead by adjusting the height and width of the view during the course of the animation. This can be done by using ValueAnimator.

    private void scaleOutAnimate() {
        final int height = mImageView.getHeight();
        final int width = mImageView.getWidth();

        ValueAnimator animatorX = ValueAnimator.ofFloat(0f, 0f);
        animatorX.setDuration(1000);

        animatorX.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int desiredWidth = (int) ((1 + valueAnimator.getAnimatedFraction()) * width);

                LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mImageView.getLayoutParams();
                params.width = desiredWidth;
                mImageView.setLayoutParams(params);

            }
        });

        ValueAnimator animatorY = ValueAnimator.ofFloat( 0f, 0f );
        animatorY.setDuration(1000);

        animatorY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int desiredHeight = (int) ((1 + valueAnimator.getAnimatedFraction()) * height);

                LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mImageView.getLayoutParams();
                params.height = desiredHeight;
                mImageView.setLayoutParams(params);

            }
        });

        AnimatorSet set = new AnimatorSet();
        set.playTogether(animatorX, animatorY);

        set.start();
    }

    private void scaleInAnimate() {

        final int height = mImageView.getHeight();
        final int width = mImageView.getWidth();

        ValueAnimator animatorX = ValueAnimator.ofFloat(0f, 0f);
        animatorX.setDuration(1000);

        animatorX.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {

                int desiredWidth = width - (int) (width * valueAnimator.getAnimatedFraction() / 2);

                LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mImageView.getLayoutParams();
                params.width = desiredWidth;
                mImageView.setLayoutParams(params);

            }
        });

        ValueAnimator animatorY = ValueAnimator.ofFloat( 0f, 0f );
        animatorY.setDuration(1000);

        animatorY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {

                int desiredHeight = height - (int) (height * valueAnimator.getAnimatedFraction() / 2);

                LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mImageView.getLayoutParams();
                params.height = desiredHeight;
                mImageView.setLayoutParams(params);

            }
        });

        AnimatorSet set = new AnimatorSet();
        set.playTogether(animatorX, animatorY);

        set.start();

    }


No comments: