1 page.title=Crossfading Two Views 2 trainingnavtop=true 3 4 5 @jd:body 6 7 <div id="tb-wrapper"> 8 <div id="tb"> 9 <h2> 10 This lesson teaches you to: 11 </h2> 12 <ol> 13 <li> 14 <a href="#views">Create the Views</a> 15 </li> 16 <li> 17 <a href="#setup">Set up the Animation</a> 18 </li> 19 <li> 20 <a href="#animate">Crossfade the Views</a> 21 </li> 22 </ol> 23 </div> 24 </div> 25 26 <p> 27 Crossfade animations (also know as dissolve) gradually fade out one UI component while simultaneously fading in 28 another. This animation is useful for situations where you want to switch content or views 29 in your app. Crossfades are very subtle and short but offer a fluid transition from one screen to the 30 next. When you don't use them, however, transitions often feel abrupt or hurried. 31 </p> 32 <p>Here's an example of a crossfade from a progress indicator to some text content. 33 </p> 34 35 <div class="framed-galaxynexus-land-span-8"> 36 <video class="play-on-hover" autoplay> 37 <source src="anim_crossfade.mp4" type="video/mp4"> 38 <source src="anim_crossfade.webm" type="video/webm"> 39 <source src="anim_crossfade.ogv" type="video/ogg"> 40 </video> 41 </div> 42 <div class="figure-caption"> 43 Crossfade animation 44 <div class="video-instructions"> </div> 45 </div> 46 47 <p> 48 If you want to jump ahead and see a full working example, 49 <a href="{@docRoot}shareables/training/Animations.zip">download</a> 50 and run the sample app and select the Crossfade example. 51 See the following files for the code implementation: 52 </p> 53 <ul> 54 <li> 55 <code>src/CrossfadeActivity.java</code> 56 </li> 57 <li> 58 <code>layout/activity_crossfade.xml</code> 59 </li> 60 <li> 61 <code>menu/activity_crossfade.xml</code> 62 </li> 63 </ul> 64 <h2 id="views"> 65 Create the Views 66 </h2> 67 <p> 68 Create the two views that you want to crossfade. The following example creates a progress 69 indicator and a scrollable text view: 70 </p> 71 <pre> 72 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 73 android:layout_width="match_parent" 74 android:layout_height="match_parent"> 75 76 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 77 android:id="@+id/content" 78 android:layout_width="match_parent" 79 android:layout_height="match_parent"> 80 81 <TextView style="?android:textAppearanceMedium" 82 android:lineSpacingMultiplier="1.2" 83 android:layout_width="match_parent" 84 android:layout_height="wrap_content" 85 android:text="@string/lorem_ipsum" 86 android:padding="16dp" /> 87 88 </ScrollView> 89 90 <ProgressBar android:id="@+id/loading_spinner" 91 style="?android:progressBarStyleLarge" 92 android:layout_width="wrap_content" 93 android:layout_height="wrap_content" 94 android:layout_gravity="center" /> 95 96 </FrameLayout> 97 </pre> 98 <h2 id="setup"> 99 Set up the Animation 100 </h2> 101 <p> 102 To set up the animation: 103 </p> 104 <ol> 105 <li>Create member variables for the views that you want to crossfade. You need 106 these references later when modifying the views during the animation. 107 </li> 108 <li>For the view that is being faded in, set its visibility to {@link 109 android.view.View#GONE}. This prevents the view from taking up layout space and omits it 110 from layout calculations, speeding up processing. 111 </li> 112 <li>Cache the <code>{@link android.R.integer#config_shortAnimTime}</code> 113 system property in a member variable. This property defines a standard 114 "short" duration for the animation. This duration is ideal for subtle animations or 115 animations that occur very frequently. {@link android.R.integer#config_longAnimTime} and 116 {@link android.R.integer#config_mediumAnimTime} are also available if you wish to use them. 117 </li> 118 </ol> 119 <p> 120 Here's an example using the layout from the previous code snippet as the activity content 121 view: 122 </p> 123 <pre> 124 public class CrossfadeActivity extends Activity { 125 126 private View mContentView; 127 private View mLoadingView; 128 private int mShortAnimationDuration; 129 130 ... 131 132 @Override 133 protected void onCreate(Bundle savedInstanceState) { 134 super.onCreate(savedInstanceState); 135 setContentView(R.layout.activity_crossfade); 136 137 mContentView = findViewById(R.id.content); 138 mLoadingView = findViewById(R.id.loading_spinner); 139 140 // Initially hide the content view. 141 mContentView.setVisibility(View.GONE); 142 143 // Retrieve and cache the system's default "short" animation time. 144 mShortAnimationDuration = getResources().getInteger( 145 android.R.integer.config_shortAnimTime); 146 } 147 148 </pre> 149 <h2 id="animate"> 150 Crossfade the Views 151 </h2> 152 <p> 153 Now that the views are properly set up, crossfade them by doing the following: 154 </p> 155 <ol> 156 <li>For the view that is fading in, set the alpha value to <code>0</code> and the visibility 157 to {@link android.view.View#VISIBLE}. (Remember that it was initially set to {@link 158 android.view.View#GONE}.) This makes the view visible but completely transparent. 159 </li> 160 <li>For the view that is fading in, animate its alpha value from <code>0</code> to 161 <code>1</code>. At the same time, for the view that is fading out, animate the alpha value 162 from <code>1</code> to <code>0</code>. 163 </li> 164 <li>Using {@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()} 165 in an {@link android.animation.Animator.AnimatorListener}, set the visibility of the view 166 that was fading out to {@link android.view.View#GONE}. Even though the alpha value is <code>0</code>, 167 setting the view's visibility to {@link android.view.View#GONE} prevents the view from taking 168 up layout space and omits it from layout calculations, speeding up processing. 169 </li> 170 </ol> 171 <p> 172 The following method shows an example of how to do this: 173 </p> 174 <pre> 175 private View mContentView; 176 private View mLoadingView; 177 private int mShortAnimationDuration; 178 179 ... 180 181 private void crossfade() { 182 183 // Set the content view to 0% opacity but visible, so that it is visible 184 // (but fully transparent) during the animation. 185 mContentView.setAlpha(0f); 186 mContentView.setVisibility(View.VISIBLE); 187 188 // Animate the content view to 100% opacity, and clear any animation 189 // listener set on the view. 190 mContentView.animate() 191 .alpha(1f) 192 .setDuration(mShortAnimationDuration) 193 .setListener(null); 194 195 // Animate the loading view to 0% opacity. After the animation ends, 196 // set its visibility to GONE as an optimization step (it won't 197 // participate in layout passes, etc.) 198 mHideView.animate() 199 .alpha(0f) 200 .setDuration(mShortAnimationDuration) 201 .setListener(new AnimatorListenerAdapter() { 202 @Override 203 public void onAnimationEnd(Animator animation) { 204 mHideView.setVisibility(View.GONE); 205 } 206 }); 207 } 208 </pre>