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