10

As by object, I would reproduce fade effect between two layout. Now I've this situation:

LinearLayout l;
LinearLayout l2;

To switch between them I've used

l.setVisibility(View.GONE);
l2.setVisibility(View.VISIBLE);

I want add fade effect between this transiction, how I can do it?

CeccoCQ
  • 3,746
  • 12
  • 50
  • 81

3 Answers3

22

Here is a working solution to cross fade between 2 layouts:

public class CrossFadeActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.crossfade);

    final View l1 = findViewById(R.id.l1);
    final View l2 = findViewById(R.id.l2);

    final Animation fadeOut = AnimationUtils.loadAnimation(CrossFadeActivity.this, R.anim.fade_out);
    final Animation fadeIn = AnimationUtils.loadAnimation(CrossFadeActivity.this, R.anim.fade_in);

    findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            fadeOut.setAnimationListener(new AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    l1.setVisibility(View.GONE);
                }
            });
            l1.startAnimation(fadeOut);
            l2.setVisibility(View.VISIBLE);
            l2.startAnimation(fadeIn);
        }
    });
    findViewById(R.id.button2).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            fadeOut.setAnimationListener(new AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    l2.setVisibility(View.GONE);
                }
            });
            l2.startAnimation(fadeOut);
            l1.setVisibility(View.VISIBLE);
            l1.startAnimation(fadeIn);
        }
    });
}
}

crossfade.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<LinearLayout
    android:id="@+id/l1"
    android:layout_width="fill_parent"
    android:layout_height="300dip"
    android:orientation="vertical" 
    android:background="@drawable/someimage"
    >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

</LinearLayout>

<RelativeLayout
    android:id="@+id/l2"
    android:layout_width="fill_parent"
    android:layout_height="300dip"
    android:orientation="vertical" 
    android:background="@drawable/someimage2"
    android:visibility="gone"
    >

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" 
        android:layout_centerInParent="true"
        />

</RelativeLayout>

</RelativeLayout>

Where l1 and l2 are 2 random example layouts. The trick is to put them in XML such that they overlap each other (e.g. in a RelativeLayout) with visible / gone, add listeners to the animations to toggle the visibility on finish, and set the view which has to fade in to visible before the animation starts, otherwise the animation will not be visible.

I put the buttons with the listeners to toggle the animation in the layouts itself, because I need to implement it that way but the click listener can be of course somewhere else (if it's only one it should be used in combination with some flag or check to know how to toggle).

These are the animation files. They have to be stored in folder res/anim:

fade_in.xml

<?xml version="1.0" encoding="UTF-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fillAfter="true"
android:fromAlpha="0.0"
android:toAlpha="1.0" />

fade_out.xml

<?xml version="1.0" encoding="UTF-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fillAfter="true"
android:fromAlpha="1.0"
android:toAlpha="0" />

UPDATE:

Instead of using R.anim.fade_in, you can use the default fade_in from Android API (android.R.fade_in):

final Animation fadeIn = AnimationUtils.loadAnimation(CrossFadeActivity.this, android.R.anim.fade_in);

Using android.R.anim.fade_in, you will not need to create the file res/anim/fade_in.xml.

Android has a package with some useful animations on android.R.anim: http://developer.android.com/reference/android/R.anim.html

Erick M. Sprengel
  • 1,921
  • 1
  • 17
  • 20
User
  • 31,811
  • 40
  • 131
  • 232
  • 2
    You can also use `.bringToFront()` method to reverse the z-order of the relative layouts in case the user needs to interact with the foreground. This answer just covers the animation aspect. – the_prole Jan 02 '16 at 01:44
4

Using R.anim.fade_out & .R.anim.fade_in you can create an animation which does this. I don't know much about this myself but heres a tutorial regarding animations in android: Animation Tutorial

P.S. This tutorial is not mine thus credit does not go out to me.

Edit:

AnimationSet set = new AnimationSet(true);

Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(50);
set.addAnimation(animation);

animation = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0.0f,Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -1.0f,Animation.RELATIVE_TO_SELF, 0.0f
);
animation.setDuration(100);
set.addAnimation(animation);

LayoutAnimationController controller = new LayoutAnimationController(set, 0.5f);
l.setLayoutAnimation(controller);

Fade out Animation

public static Animation runFadeOutAnimationOn(Activity ctx, View target) {
  Animation animation = AnimationUtils.loadAnimation(ctx,android.R.anim.fade_out);
  target.startAnimation(animation);
  return animation;
}

I'm guessing you can try something like this, I copy pasted the animation from the tutorial I don't know what it does exactly as I have no experience with Android development. Another example could be Example 2

  • 1
    I want use android.R.anim.fade_in and fade_out and I've read something about method overridePendingTransiction. But I don't understand how set animation to LinearLayout. Can you help me? – CeccoCQ Dec 26 '10 at 13:28
  • The tutorial covers the anim.fade_in and fade_out, if you scroll down abit you can see example code! This should get you going I think. –  Dec 26 '10 at 13:38
3

Since android 3.0 you can use

android:animateLayoutChanges="true"

in a layout in xml and any changes to this specific layouts content at run time will be animated. For example, in your case, you will need to set this attribute for the parent for the parent layout of l and l2 e.g

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="me.kalem.android.RegistrationActivity"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:animateLayoutChanges="true"
    android:padding="20dp">

    <LinearLayout
        android:id="@+id/l1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:visibility="visible">

    ........

    </LinearLayout>

    <LinearLayout
        android:id="@+id/l2"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:visibility="gone">

    ........

    </LinearLayout>

</LinearLayout>

Now hiding l1 and showing l2 at runtime will be animated.

binW
  • 13,220
  • 11
  • 56
  • 69