AbsActionBarView.java revision 9a5cc2810bbbcb0eab4579aa4131039820d92101
1/*
2 * Copyright (C) 2011 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 */
16package com.android.internal.widget;
17
18import com.android.internal.view.menu.ActionMenuPresenter;
19import com.android.internal.view.menu.ActionMenuView;
20
21import android.animation.Animator;
22import android.animation.AnimatorSet;
23import android.animation.ObjectAnimator;
24import android.animation.TimeInterpolator;
25import android.content.Context;
26import android.util.AttributeSet;
27import android.view.View;
28import android.view.ViewGroup;
29import android.view.animation.DecelerateInterpolator;
30
31public abstract class AbsActionBarView extends ViewGroup {
32    protected ActionMenuView mMenuView;
33    protected ActionMenuPresenter mActionMenuPresenter;
34    protected ActionBarContainer mSplitView;
35
36    protected Animator mVisibilityAnim;
37    protected final VisibilityAnimListener mVisAnimListener = new VisibilityAnimListener();
38
39    private static final TimeInterpolator sAlphaInterpolator = new DecelerateInterpolator();
40
41    private static final int FADE_DURATION = 200;
42
43    public AbsActionBarView(Context context) {
44        super(context);
45    }
46
47    public AbsActionBarView(Context context, AttributeSet attrs) {
48        super(context, attrs);
49    }
50
51    public AbsActionBarView(Context context, AttributeSet attrs, int defStyle) {
52        super(context, attrs, defStyle);
53    }
54
55    public void setSplitView(ActionBarContainer splitView) {
56        mSplitView = splitView;
57    }
58
59    /**
60     * @return Current visibility or if animating, the visibility being animated to.
61     */
62    public int getAnimatedVisibility() {
63        if (mVisibilityAnim != null) {
64            return mVisAnimListener.mFinalVisibility;
65        }
66        return getVisibility();
67    }
68
69    public void animateToVisibility(int visibility) {
70        if (mVisibilityAnim != null) {
71            mVisibilityAnim.cancel();
72        }
73        if (visibility == VISIBLE) {
74            if (getVisibility() != VISIBLE) {
75                setAlpha(0);
76                if (mSplitView != null && mMenuView != null) {
77                    mMenuView.setAlpha(0);
78                }
79            }
80            ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 1);
81            anim.setDuration(FADE_DURATION);
82            anim.setInterpolator(sAlphaInterpolator);
83            if (mSplitView != null && mMenuView != null) {
84                AnimatorSet set = new AnimatorSet();
85                ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, "alpha", 1);
86                splitAnim.setDuration(FADE_DURATION);
87                set.addListener(mVisAnimListener.withFinalVisibility(visibility));
88                set.play(anim).with(splitAnim);
89                set.start();
90            } else {
91                anim.addListener(mVisAnimListener.withFinalVisibility(visibility));
92                anim.start();
93            }
94        } else {
95            ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 0);
96            anim.setDuration(FADE_DURATION);
97            anim.setInterpolator(sAlphaInterpolator);
98            if (mSplitView != null && mMenuView != null) {
99                AnimatorSet set = new AnimatorSet();
100                ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, "alpha", 0);
101                splitAnim.setDuration(FADE_DURATION);
102                set.addListener(mVisAnimListener.withFinalVisibility(visibility));
103                set.play(anim).with(splitAnim);
104                set.start();
105            } else {
106                anim.addListener(mVisAnimListener.withFinalVisibility(visibility));
107                anim.start();
108            }
109        }
110    }
111
112    @Override
113    public void setVisibility(int visibility) {
114        if (mVisibilityAnim != null) {
115            mVisibilityAnim.end();
116        }
117        super.setVisibility(visibility);
118    }
119
120    public boolean showOverflowMenu() {
121        if (mActionMenuPresenter != null) {
122            return mActionMenuPresenter.showOverflowMenu();
123        }
124        return false;
125    }
126
127    public void postShowOverflowMenu() {
128        post(new Runnable() {
129            public void run() {
130                showOverflowMenu();
131            }
132        });
133    }
134
135    public boolean hideOverflowMenu() {
136        if (mActionMenuPresenter != null) {
137            return mActionMenuPresenter.hideOverflowMenu();
138        }
139        return false;
140    }
141
142    public boolean isOverflowMenuShowing() {
143        if (mActionMenuPresenter != null) {
144            return mActionMenuPresenter.isOverflowMenuShowing();
145        }
146        return false;
147    }
148
149    public boolean isOverflowReserved() {
150        return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved();
151    }
152
153    public void dismissPopupMenus() {
154        if (mActionMenuPresenter != null) {
155            mActionMenuPresenter.dismissPopupMenus();
156        }
157    }
158
159    protected int measureChildView(View child, int availableWidth, int childSpecHeight,
160            int spacing) {
161        child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
162                childSpecHeight);
163
164        availableWidth -= child.getMeasuredWidth();
165        availableWidth -= spacing;
166
167        return Math.max(0, availableWidth);
168    }
169
170    protected int positionChild(View child, int x, int y, int contentHeight) {
171        int childWidth = child.getMeasuredWidth();
172        int childHeight = child.getMeasuredHeight();
173        int childTop = y + (contentHeight - childHeight) / 2;
174
175        child.layout(x, childTop, x + childWidth, childTop + childHeight);
176
177        return childWidth;
178    }
179
180    protected int positionChildInverse(View child, int x, int y, int contentHeight) {
181        int childWidth = child.getMeasuredWidth();
182        int childHeight = child.getMeasuredHeight();
183        int childTop = y + (contentHeight - childHeight) / 2;
184
185        child.layout(x - childWidth, childTop, x, childTop + childHeight);
186
187        return childWidth;
188    }
189
190    protected class VisibilityAnimListener implements Animator.AnimatorListener {
191        private boolean mCanceled = false;
192        int mFinalVisibility;
193
194        public VisibilityAnimListener withFinalVisibility(int visibility) {
195            mFinalVisibility = visibility;
196            return this;
197        }
198
199        @Override
200        public void onAnimationStart(Animator animation) {
201            setVisibility(VISIBLE);
202            mVisibilityAnim = animation;
203            mCanceled = false;
204        }
205
206        @Override
207        public void onAnimationEnd(Animator animation) {
208            if (mCanceled) return;
209
210            mVisibilityAnim = null;
211            setVisibility(mFinalVisibility);
212            if (mSplitView != null && mMenuView != null) {
213                mMenuView.setVisibility(mFinalVisibility);
214            }
215        }
216
217        @Override
218        public void onAnimationCancel(Animator animation) {
219            mCanceled = true;
220        }
221
222        @Override
223        public void onAnimationRepeat(Animator animation) {
224        }
225    }
226}
227