1 /* 2 * Copyright 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.animationsdemo; 18 19 import android.animation.Animator; 20 import android.animation.AnimatorListenerAdapter; 21 import android.app.Activity; 22 import android.content.Intent; 23 import android.os.Bundle; 24 import android.support.v4.app.NavUtils; 25 import android.view.Menu; 26 import android.view.MenuItem; 27 import android.view.View; 28 29 /** 30 * This sample demonstrates cross-fading between two overlapping views. 31 * 32 * <p>In this sample, the two overlapping views are a loading indicator and some text content. The 33 * active view is toggled by touching the toggle button in the action bar. In real-world 34 * applications, this toggle would occur as soon as content was available. Note that if content is 35 * immediately available, a loading spinner shouldn't be presented and there should be no 36 * animation.</p> 37 */ 38 public class CrossfadeActivity extends Activity { 39 /** 40 * The flag indicating whether content is loaded (text is shown) or not (loading spinner is 41 * shown). 42 */ 43 private boolean mContentLoaded; 44 45 /** 46 * The view (or view group) containing the content. This is one of two overlapping views. 47 */ 48 private View mContentView; 49 50 /** 51 * The view containing the loading indicator. This is the other of two overlapping views. 52 */ 53 private View mLoadingView; 54 55 /** 56 * The system "short" animation time duration, in milliseconds. This duration is ideal for 57 * subtle animations or animations that occur very frequently. 58 */ 59 private int mShortAnimationDuration; 60 61 @Override onCreate(Bundle savedInstanceState)62 protected void onCreate(Bundle savedInstanceState) { 63 super.onCreate(savedInstanceState); 64 setContentView(R.layout.activity_crossfade); 65 66 mContentView = findViewById(R.id.content); 67 mLoadingView = findViewById(R.id.loading_spinner); 68 69 // Initially hide the content view. 70 mContentView.setVisibility(View.GONE); 71 72 // Retrieve and cache the system's default "short" animation time. 73 mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime); 74 } 75 76 @Override onCreateOptionsMenu(Menu menu)77 public boolean onCreateOptionsMenu(Menu menu) { 78 super.onCreateOptionsMenu(menu); 79 getMenuInflater().inflate(R.menu.activity_crossfade, menu); 80 return true; 81 } 82 83 @Override onOptionsItemSelected(MenuItem item)84 public boolean onOptionsItemSelected(MenuItem item) { 85 switch (item.getItemId()) { 86 case android.R.id.home: 87 // Navigate "up" the demo structure to the launchpad activity. 88 // See http://developer.android.com/design/patterns/navigation.html for more. 89 NavUtils.navigateUpTo(this, new Intent(this, MainActivity.class)); 90 return true; 91 92 case R.id.action_toggle: 93 // Toggle whether content is loaded. 94 mContentLoaded = !mContentLoaded; 95 showContentOrLoadingIndicator(mContentLoaded); 96 return true; 97 } 98 99 return super.onOptionsItemSelected(item); 100 } 101 102 /** 103 * Cross-fades between {@link #mContentView} and {@link #mLoadingView}. 104 */ showContentOrLoadingIndicator(boolean contentLoaded)105 private void showContentOrLoadingIndicator(boolean contentLoaded) { 106 // Decide which view to hide and which to show. 107 final View showView = contentLoaded ? mContentView : mLoadingView; 108 final View hideView = contentLoaded ? mLoadingView : mContentView; 109 110 // Set the "show" view to 0% opacity but visible, so that it is visible 111 // (but fully transparent) during the animation. 112 showView.setAlpha(0f); 113 showView.setVisibility(View.VISIBLE); 114 115 // Animate the "show" view to 100% opacity, and clear any animation listener set on 116 // the view. Remember that listeners are not limited to the specific animation 117 // describes in the chained method calls. Listeners are set on the 118 // ViewPropertyAnimator object for the view, which persists across several 119 // animations. 120 showView.animate() 121 .alpha(1f) 122 .setDuration(mShortAnimationDuration) 123 .setListener(null); 124 125 // Animate the "hide" view to 0% opacity. After the animation ends, set its visibility 126 // to GONE as an optimization step (it won't participate in layout passes, etc.) 127 hideView.animate() 128 .alpha(0f) 129 .setDuration(mShortAnimationDuration) 130 .setListener(new AnimatorListenerAdapter() { 131 @Override 132 public void onAnimationEnd(Animator animation) { 133 hideView.setVisibility(View.GONE); 134 } 135 }); 136 } 137 } 138