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