java - Android adding simple animations while setvisibility(view.Gone)


Translate

I have designed a simple layout.I have finished the design without animation, but now I want to add animations when textview click event and I don't know how to use it. Did my xml design looks good or not? Any suggestions would be appreciated.

My XML

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:longClickable="false"
    android:orientation="vertical"
    android:weightSum="16" >

<LinearLayout 
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#00DDA0"
    android:layout_weight="3" >
</LinearLayout>
 <TextView
        android:id="@+id/Information1"
        android:layout_width="match_parent"
        android:layout_height="1dp" 
        android:text="Child Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>

 <LinearLayout
     android:id="@+id/layout1"
     android:layout_width="fill_parent"
     android:layout_height="0dp"
     android:layout_weight="8.5"
     android:background="#BBBBBB"
     android:orientation="vertical" >

     <TextView
         android:id="@+id/textView1"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
 </LinearLayout>

  <TextView
        android:id="@+id/Information2"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Parent Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
  <LinearLayout 
          android:id="@+id/layout2"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView2"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
   <TextView
        android:id="@+id/Information3"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Siblings" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
   <LinearLayout 
          android:id="@+id/layout3"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView3"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
    <TextView
        android:id="@+id/Information4"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Teacher Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
    <LinearLayout 
          android:id="@+id/layout4"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView4"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
     <TextView
        android:id="@+id/Information5"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Grade Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
     <LinearLayout 
          android:id="@+id/layout5"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView5"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
      <TextView
        android:id="@+id/Information6"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Health Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
      <LinearLayout 
          android:id="@+id/layout6"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
    <TextView
         android:id="@+id/textView5"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" 
         android:layout_weight="8.5" />
      </LinearLayout>

</LinearLayout>

My java

public class Certify_Info extends Activity {

    private static TextView tv2,tv3,tv5,tv6,tv4,tv1;
    private static LinearLayout l1,l2,l3,l4,l5,l6;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_certify__info);

        tv1=(TextView) findViewById(R.id.Information1);
        tv2=(TextView) findViewById(R.id.Information2);
        tv3=(TextView) findViewById(R.id.Information3);
        tv4=(TextView) findViewById(R.id.Information4);
        tv5=(TextView) findViewById(R.id.Information5);
        tv6=(TextView) findViewById(R.id.Information6); 

        l1=(LinearLayout) findViewById(R.id.layout1);
        l2=(LinearLayout) findViewById(R.id.layout2);
        l3=(LinearLayout) findViewById(R.id.layout3);
        l4=(LinearLayout) findViewById(R.id.layout4);
        l5=(LinearLayout) findViewById(R.id.layout5);
        l6=(LinearLayout) findViewById(R.id.layout6); 

        l2.setVisibility(View.GONE);
        l3.setVisibility(View.GONE); 
        l4.setVisibility(View.GONE); 
        l5.setVisibility(View.GONE);
        l6.setVisibility(View.GONE);

        tv1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l1.setVisibility(View.VISIBLE);
            }
        });
        tv2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l2.setVisibility(View.VISIBLE);
            }
        });
        tv3.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l3.setVisibility(View.VISIBLE);

            }
        });
        tv4.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l4.setVisibility(View.VISIBLE); 
            }
        });
        tv5.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l6.setVisibility(View.GONE);
                l5.setVisibility(View.VISIBLE); 
            }
        });
        tv6.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.VISIBLE);
            }
        });

    }
}

All Answers
  • Translate

    You can do two things to add animations, first you can let android animate layout changes for you. That way every time you change something in the layout like changing view visibility or view positions android will automatically create fade/transition animations. To use that set

    android:animateLayoutChanges="true"
    

    on the root node in your layout.

    Your second option would be to manually add animations. For this I suggest you use the new animation API introduced in Android 3.0 (Honeycomb). I can give you a few examples:

    This fades out a View:

    view.animate().alpha(0.0f);
    

    This fades it back in:

    view.animate().alpha(1.0f);
    

    This moves a View down by its height:

    view.animate().translationY(view.getHeight());
    

    This returns the View to its starting position after it has been moved somewhere else:

    view.animate().translationY(0);
    

    You can also use setDuration() to set the duration of the animation. For example this fades out a View over a period of 2 seconds:

    view.animate().alpha(0.0f).setDuration(2000);
    

    And you can combine as many animations as you like, for example this fades out a View and moves it down at the same time over a period of 0.3 seconds:

    view.animate()
            .translationY(view.getHeight())
            .alpha(0.0f)
            .setDuration(300);
    

    And you can also assign a listener to the animation and react to all kinds of events. Like when the animation starts, when it ends or repeats etc. By using the abstract class AnimatorListenerAdapter you don't have to implement all callbacks of AnimatorListener at once but only those you need. This makes the code more readable. For example the following code fades out a View moves it down by its height over a period of 0.3 seconds (300 milliseconds) and when the animation is done its visibility is set to View.GONE.

    view.animate()
            .translationY(view.getHeight())
            .alpha(0.0f)
            .setDuration(300)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    view.setVisibility(View.GONE);
                }
            });
    

  • Translate

    Please check this link. Which will allow animations like L2R, R2L, T2B, B2T animations.

    This code shows animation from left to right

    TranslateAnimation animate = new TranslateAnimation(0,view.getWidth(),0,0);
    animate.setDuration(500);
    animate.setFillAfter(true);
    view.startAnimation(animate);
    view.setVisibility(View.GONE);
    

    if you want to do it from R2L then use

    TranslateAnimation animate = new TranslateAnimation(0,-view.getWidth(),0,0);
    

    for top to bottom as

    TranslateAnimation animate = new TranslateAnimation(0,0,0,view.getHeight());
    

    and vice a versa..


  • Translate

    The easiest way to animate Visibility changes is use Transition API which available in support (androidx) package. Just call TransitionManager.beginDelayedTransition method then change visibility of the view. There are several default transitions like Fade, Slide.

    import androidx.transition.TransitionManager;
    import androidx.transition.Transition;
    import androidx.transition.Fade;
    
    private void toggle() {
        Transition transition = new Fade();
        transition.setDuration(600);
        transition.addTarget(R.id.image);
    
        TransitionManager.beginDelayedTransition(parent, transition);
        image.setVisibility(show ? View.VISIBLE : View.GONE);
    }
    

    Where parent is parent ViewGroup of animated view. Result:

    enter image description here

    Here is result with Slide transition:

    import androidx.transition.Slide;
    
    Transition transition = new Slide(Gravity.BOTTOM);
    

    enter image description here

    It is easy to write custom transition if you need something different. Here is example with CircularRevealTransition which I wrote in another answer. It shows and hide view with CircularReveal animation.

    Transition transition = new CircularRevealTransition();
    

    enter image description here

    android:animateLayoutChanges="true" option does same thing, it just uses AutoTransition as transition.


  • Translate

    Based on the answer of @Xaver Kapeller I figured out a way to create scroll animation when new views appear on the screen (and also animation to hide them).

    It goes from this state:

    • Button
    • Last Button

    to

    • Button
    • Button 1
    • Button 2
    • Button 3
    • Button 4
    • Last Button

    and viceversa.

    So, when the user clicks on the first button, the elements "Button 1", "Button 2", "Button 3" and "Button 4" will appear using fade animation and the element "Last Button" will move down till end. The height of the layout will change as well, allowing using scroll view properly.

    This is the code to show elements with animation:

    private void showElements() {
        // Precondition
        if (areElementsVisible()) {
            Log.w(TAG, "The view is already visible. Nothing to do here");
            return;
        }
    
        // Animate the hidden linear layout as visible and set
        // the alpha as 0.0. Otherwise the animation won't be shown
        mHiddenLinearLayout.setVisibility(View.VISIBLE);
        mHiddenLinearLayout.setAlpha(0.0f);
        mHiddenLinearLayout
                .animate()
                .setDuration(ANIMATION_TRANSITION_TIME)
                .alpha(1.0f)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        updateShowElementsButton();
                        mHiddenLinearLayout.animate().setListener(null);
                    }
                })
        ;
    
        mLastButton
                .animate()
                .setDuration(ANIMATION_TRANSITION_TIME)
                .translationY(mHiddenLinearLayoutHeight);
    
        // Update the high of all the elements relativeLayout
        LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();
    
        // TODO: Add vertical margins
        layoutParams.height = mLastButton.getHeight() + mHiddenLinearLayoutHeight;
    }
    

    and this is the code to hide elements of the animation:

    private void hideElements() {
        // Precondition
        if (!areElementsVisible()) {
            Log.w(TAG, "The view is already non-visible. Nothing to do here");
            return;
        }
    
        // Animate the hidden linear layout as visible and set
        mHiddenLinearLayout
                .animate()
                .setDuration(ANIMATION_TRANSITION_TIME)
                .alpha(0.0f)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        Log.v(TAG, "Animation ended. Set the view as gone");
                        super.onAnimationEnd(animation);
                        mHiddenLinearLayout.setVisibility(View.GONE);
                        // Hack: Remove the listener. So it won't be executed when
                        // any other animation on this view is executed
                        mHiddenLinearLayout.animate().setListener(null);
                        updateShowElementsButton();
                    }
                })
        ;
    
        mLastButton
                .animate()
                .setDuration(ANIMATION_TRANSITION_TIME)
                .translationY(0);
    
        // Update the high of all the elements relativeLayout
        LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();
    
        // TODO: Add vertical margins
        layoutParams.height = mLastButton.getHeight();
    }
    

    Note there is a simple hack on the method to hide the animation. On the animation listener mHiddenLinearLayout, I had to remove the listener itself by using:

    mHiddenLinearLayout.animate().setListener(null);
    

    This is because once an animation listener is attached to an view, the next time when any animation is executed in this view, the listener will be executed as well. This might be a bug in the animation listener.

    The source code of the project is on GitHub: https://github.com/jiahaoliuliu/ViewsAnimated

    Happy coding!

    Update: For any listener attached to the views, it should be removed after the animation ends. This is done by using

    view.animate().setListener(null);
    

  • Translate

    Try adding this line to axml parent layout

     android:animateLayoutChanges="true"
    

  • Translate

    I was able to show/hide a menu this way:

    MenuView.java (extends FrameLayout)

    private final int ANIMATION_DURATION = 500;
    
    public void showMenu()
    {
        setVisibility(View.VISIBLE);
        animate()
                .alpha(1f)
                .setDuration(ANIMATION_DURATION)
                .setListener(null);
    }
    
    private void hideMenu()
    {
        animate()
                .alpha(0f)
                .setDuration(ANIMATION_DURATION)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        setVisibility(View.GONE);
                    }
                });
    }
    

    Source