Search code examples
androidanimationtranslate-animation

android: how to visible portion of a view with animation?


I have a invisible View behind of another View. I want to make this view visible with a translate animation and show only a part of the right side view. like this: sample animation

I don't want to use 9 patch image and resize that. this animation named "peek in"" in MS-PowerPoint.


Solution

  • You could try something like this

    1) create a drawable resource rectangle_curved.xml as shown below

           <shape xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle" android:padding="10dp">
            <solid android:color="#FFFFFF"/>
            <corners
                android:bottomRightRadius="350dp"
                android:bottomLeftRadius="0dp"
                android:topLeftRadius="0dp"
                android:topRightRadius="350dp"/>
            <stroke android:color="#50000000" android:width="2dp"/>
        </shape>
    

    2) Set this as the background of the view which is expanding and collapsing. Here I have used a Framelayout which is expanding and collapsing

         <FrameLayout
            android:id="@+id/shape"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:background="@drawable/rectangle_curved"/>
    

    3) Create a class to handle the expand/collapse animation as follows

            public class ResizeAnimation extends Animation {
                private int mWidth;
                private int mInitialWidth;
                private View mView;
    
                public ResizeAnimation(View view, int width) {
                    mView = view;
                    mWidth = width;
                    mInitialWidth = view.getWidth();
                }
    
                @Override
                protected void applyTransformation(float interpolatedTime, Transformation t) {
                    int newWidth = mInitialWidth + (int) ((mWidth - mInitialWidth) * interpolatedTime);
                    mView.getLayoutParams().width = newWidth;
                    mView.requestLayout();
                }
    
                @Override
                public void initialize(int width, int height, int parentWidth, int parentHeight) {
                    super.initialize(width, height, parentWidth, parentHeight);
                }
    
                @Override
                public boolean willChangeBounds() {
                    return true;
                }
           }            
    

    4) Finally, use it like this. Create a function to handle animation as follows

         private void animate(View shapeView, boolean isExpand) {  
            int width = isExpand ? 500 : 0; // 500 is the max width in pixels , you ca change it
            ResizeAnimation anim = new ResizeAnimation(shapeView, width);
            anim.setDuration(500);
            shape.startAnimation(anim);
         }
    

    and call this function as follows

    for expand animation : animate(myBackgroundView, true)

    for collapse animation : animate(myBackgroundView, false)

    EDIT: in this line of step 4: int width = isExpand ? 500 : 0; use 1 instead of 0. 0 not work properly. I don't know why.

    private void animate(View view, boolean isExpand) {
        int width = isExpand ? 200 : 1; // 200 is the max width in pixels.
        //use a factor for same width on all screen size.
        DisplayMetrics metrics = getResources().getDisplayMetrics();
        int factor =(int)  metrics.density;
        ResizeAnimation anim = new ResizeAnimation(view, width * factor);
        anim.setDuration(500);
        view.startAnimation(anim);
    }