page.title=Crossfading Two Views trainingnavtop=true @jd:body
Crossfade animations (also know as dissolve) gradually fade out one UI component while simultaneously fading in another. This animation is useful for situations where you want to switch content or views in your app. Crossfades are very subtle and short but offer a fluid transition from one screen to the next. When you don't use them, however, transitions often feel abrupt or hurried.
Here's an example of a crossfade from a progress indicator to some text content.
If you want to jump ahead and see a full working example, download and run the sample app and select the Crossfade example. See the following files for the code implementation:
src/CrossfadeActivity.java
layout/activity_crossfade.xml
menu/activity_crossfade.xml
Create the two views that you want to crossfade. The following example creates a progress indicator and a scrollable text view:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView style="?android:textAppearanceMedium" android:lineSpacingMultiplier="1.2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/lorem_ipsum" android:padding="16dp" /> </ScrollView> <ProgressBar android:id="@+id/loading_spinner" style="?android:progressBarStyleLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> </FrameLayout>
To set up the animation:
{@link android.R.integer#config_shortAnimTime}
system property in a member variable. This property defines a standard
"short" duration for the animation. This duration is ideal for subtle animations or
animations that occur very frequently. {@link android.R.integer#config_longAnimTime} and
{@link android.R.integer#config_mediumAnimTime} are also available if you wish to use them.
Here's an example using the layout from the previous code snippet as the activity content view:
public class CrossfadeActivity extends Activity { private View mContentView; private View mLoadingView; private int mShortAnimationDuration; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_crossfade); mContentView = findViewById(R.id.content); mLoadingView = findViewById(R.id.loading_spinner); // Initially hide the content view. mContentView.setVisibility(View.GONE); // Retrieve and cache the system's default "short" animation time. mShortAnimationDuration = getResources().getInteger( android.R.integer.config_shortAnimTime); }
Now that the views are properly set up, crossfade them by doing the following:
0
and the visibility
to {@link android.view.View#VISIBLE}. (Remember that it was initially set to {@link
android.view.View#GONE}.) This makes the view visible but completely transparent.
0
to
1
. At the same time, for the view that is fading out, animate the alpha value
from 1
to 0
.
0
,
setting the view's visibility to {@link android.view.View#GONE} prevents the view from taking
up layout space and omits it from layout calculations, speeding up processing.
The following method shows an example of how to do this:
private View mContentView; private View mLoadingView; private int mShortAnimationDuration; ... private void crossfade() { // Set the content view to 0% opacity but visible, so that it is visible // (but fully transparent) during the animation. mContentView.setAlpha(0f); mContentView.setVisibility(View.VISIBLE); // Animate the content view to 100% opacity, and clear any animation // listener set on the view. mContentView.animate() .alpha(1f) .setDuration(mShortAnimationDuration) .setListener(null); // Animate the loading view to 0% opacity. After the animation ends, // set its visibility to GONE as an optimization step (it won't // participate in layout passes, etc.) mLoadingView.animate() .alpha(0f) .setDuration(mShortAnimationDuration) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mLoadingView.setVisibility(View.GONE); } }); }