AbsActionBarView.java revision 8d02deabac62c4a68a335a7b3141795466362b89
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    public void animateToVisibility(int visibility) {
60        if (mVisibilityAnim != null) {
61            mVisibilityAnim.cancel();
62        }
63        if (visibility == VISIBLE) {
64            if (getVisibility() != VISIBLE) {
65                setAlpha(0);
66                if (mSplitView != null && mMenuView != null) {
67                    mMenuView.setAlpha(0);
68                }
69            }
70            ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 1);
71            anim.setDuration(FADE_DURATION);
72            anim.setInterpolator(sAlphaInterpolator);
73            if (mSplitView != null && mMenuView != null) {
74                AnimatorSet set = new AnimatorSet();
75                ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, "alpha", 1);
76                splitAnim.setDuration(FADE_DURATION);
77                set.addListener(mVisAnimListener.withFinalVisibility(visibility));
78                set.play(anim).with(splitAnim);
79                set.start();
80            } else {
81                anim.addListener(mVisAnimListener.withFinalVisibility(visibility));
82                anim.start();
83            }
84        } else {
85            ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 0);
86            anim.setDuration(FADE_DURATION);
87            anim.setInterpolator(sAlphaInterpolator);
88            if (mSplitView != null && mMenuView != null) {
89                AnimatorSet set = new AnimatorSet();
90                ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, "alpha", 0);
91                splitAnim.setDuration(FADE_DURATION);
92                set.addListener(mVisAnimListener.withFinalVisibility(visibility));
93                set.play(anim).with(splitAnim);
94                set.start();
95            } else {
96                anim.addListener(mVisAnimListener.withFinalVisibility(visibility));
97                anim.start();
98            }
99        }
100    }
101
102    @Override
103    public void setVisibility(int visibility) {
104        if (mVisibilityAnim != null) {
105            mVisibilityAnim.end();
106        }
107        super.setVisibility(visibility);
108    }
109
110    public boolean showOverflowMenu() {
111        if (mActionMenuPresenter != null) {
112            return mActionMenuPresenter.showOverflowMenu();
113        }
114        return false;
115    }
116
117    public void postShowOverflowMenu() {
118        post(new Runnable() {
119            public void run() {
120                showOverflowMenu();
121            }
122        });
123    }
124
125    public boolean hideOverflowMenu() {
126        if (mActionMenuPresenter != null) {
127            return mActionMenuPresenter.hideOverflowMenu();
128        }
129        return false;
130    }
131
132    public boolean isOverflowMenuShowing() {
133        if (mActionMenuPresenter != null) {
134            return mActionMenuPresenter.isOverflowMenuShowing();
135        }
136        return false;
137    }
138
139    public boolean isOverflowReserved() {
140        return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved();
141    }
142
143    public void dismissPopupMenus() {
144        if (mActionMenuPresenter != null) {
145            mActionMenuPresenter.dismissPopupMenus();
146        }
147    }
148
149    protected int measureChildView(View child, int availableWidth, int childSpecHeight,
150            int spacing) {
151        child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
152                childSpecHeight);
153
154        availableWidth -= child.getMeasuredWidth();
155        availableWidth -= spacing;
156
157        return Math.max(0, availableWidth);
158    }
159
160    protected int positionChild(View child, int x, int y, int contentHeight) {
161        int childWidth = child.getMeasuredWidth();
162        int childHeight = child.getMeasuredHeight();
163        int childTop = y + (contentHeight - childHeight) / 2;
164
165        child.layout(x, childTop, x + childWidth, childTop + childHeight);
166
167        return childWidth;
168    }
169
170    protected int positionChildInverse(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 - childWidth, childTop, x, childTop + childHeight);
176
177        return childWidth;
178    }
179
180    protected class VisibilityAnimListener implements Animator.AnimatorListener {
181        private boolean mCanceled = false;
182        private int mFinalVisibility;
183
184        public VisibilityAnimListener withFinalVisibility(int visibility) {
185            mFinalVisibility = visibility;
186            return this;
187        }
188
189        @Override
190        public void onAnimationStart(Animator animation) {
191            setVisibility(VISIBLE);
192            mVisibilityAnim = animation;
193            mCanceled = false;
194        }
195
196        @Override
197        public void onAnimationEnd(Animator animation) {
198            if (mCanceled) return;
199
200            mVisibilityAnim = null;
201            setVisibility(mFinalVisibility);
202        }
203
204        @Override
205        public void onAnimationCancel(Animator animation) {
206            mCanceled = true;
207        }
208
209        @Override
210        public void onAnimationRepeat(Animator animation) {
211        }
212    }
213}
214