1 /*
2  * Copyright (C) 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.android.gallery3d.app;
18 
19 import android.content.Context;
20 import android.view.LayoutInflater;
21 import android.view.View;
22 import android.view.View.OnClickListener;
23 import android.view.ViewGroup;
24 import android.view.animation.AlphaAnimation;
25 import android.view.animation.Animation;
26 import android.widget.RelativeLayout;
27 
28 import com.android.gallery3d.R;
29 
30 import java.util.HashMap;
31 import java.util.Map;
32 
33 public class PhotoPageBottomControls implements OnClickListener {
34     public interface Delegate {
canDisplayBottomControls()35         public boolean canDisplayBottomControls();
canDisplayBottomControl(int control)36         public boolean canDisplayBottomControl(int control);
onBottomControlClicked(int control)37         public void onBottomControlClicked(int control);
refreshBottomControlsWhenReady()38         public void refreshBottomControlsWhenReady();
39     }
40 
41     private Delegate mDelegate;
42     private ViewGroup mParentLayout;
43     private ViewGroup mContainer;
44 
45     private boolean mContainerVisible = false;
46     private Map<View, Boolean> mControlsVisible = new HashMap<View, Boolean>();
47 
48     private Animation mContainerAnimIn = new AlphaAnimation(0f, 1f);
49     private Animation mContainerAnimOut = new AlphaAnimation(1f, 0f);
50     private static final int CONTAINER_ANIM_DURATION_MS = 200;
51 
52     private static final int CONTROL_ANIM_DURATION_MS = 150;
getControlAnimForVisibility(boolean visible)53     private static Animation getControlAnimForVisibility(boolean visible) {
54         Animation anim = visible ? new AlphaAnimation(0f, 1f)
55                 : new AlphaAnimation(1f, 0f);
56         anim.setDuration(CONTROL_ANIM_DURATION_MS);
57         return anim;
58     }
59 
PhotoPageBottomControls(Delegate delegate, Context context, RelativeLayout layout)60     public PhotoPageBottomControls(Delegate delegate, Context context, RelativeLayout layout) {
61         mDelegate = delegate;
62         mParentLayout = layout;
63 
64         LayoutInflater inflater = (LayoutInflater) context
65                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
66         mContainer = (ViewGroup) inflater
67                 .inflate(R.layout.photopage_bottom_controls, mParentLayout, false);
68         mParentLayout.addView(mContainer);
69 
70         for (int i = mContainer.getChildCount() - 1; i >= 0; i--) {
71             View child = mContainer.getChildAt(i);
72             child.setOnClickListener(this);
73             mControlsVisible.put(child, false);
74         }
75 
76         mContainerAnimIn.setDuration(CONTAINER_ANIM_DURATION_MS);
77         mContainerAnimOut.setDuration(CONTAINER_ANIM_DURATION_MS);
78 
79         mDelegate.refreshBottomControlsWhenReady();
80     }
81 
hide()82     private void hide() {
83         mContainer.clearAnimation();
84         mContainerAnimOut.reset();
85         mContainer.startAnimation(mContainerAnimOut);
86         mContainer.setVisibility(View.INVISIBLE);
87     }
88 
show()89     private void show() {
90         mContainer.clearAnimation();
91         mContainerAnimIn.reset();
92         mContainer.startAnimation(mContainerAnimIn);
93         mContainer.setVisibility(View.VISIBLE);
94     }
95 
refresh()96     public void refresh() {
97         boolean visible = mDelegate.canDisplayBottomControls();
98         boolean containerVisibilityChanged = (visible != mContainerVisible);
99         if (containerVisibilityChanged) {
100             if (visible) {
101                 show();
102             } else {
103                 hide();
104             }
105             mContainerVisible = visible;
106         }
107         if (!mContainerVisible) {
108             return;
109         }
110         for (View control : mControlsVisible.keySet()) {
111             Boolean prevVisibility = mControlsVisible.get(control);
112             boolean curVisibility = mDelegate.canDisplayBottomControl(control.getId());
113             if (prevVisibility.booleanValue() != curVisibility) {
114                 if (!containerVisibilityChanged) {
115                     control.clearAnimation();
116                     control.startAnimation(getControlAnimForVisibility(curVisibility));
117                 }
118                 control.setVisibility(curVisibility ? View.VISIBLE : View.INVISIBLE);
119                 mControlsVisible.put(control, curVisibility);
120             }
121         }
122         // Force a layout change
123         mContainer.requestLayout(); // Kick framework to draw the control.
124     }
125 
cleanup()126     public void cleanup() {
127         mParentLayout.removeView(mContainer);
128         mControlsVisible.clear();
129     }
130 
131     @Override
onClick(View view)132     public void onClick(View view) {
133         Boolean controlVisible = mControlsVisible.get(view);
134         if (mContainerVisible && controlVisible != null && controlVisible.booleanValue()) {
135             mDelegate.onBottomControlClicked(view.getId());
136         }
137     }
138 }
139