1640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell/* 2640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell * Copyright (C) 2011 The Android Open Source Project 3640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell * 4640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 5640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell * you may not use this file except in compliance with the License. 6640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell * You may obtain a copy of the License at 7640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell * 8640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell * http://www.apache.org/licenses/LICENSE-2.0 9640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell * 10640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell * Unless required by applicable law or agreed to in writing, software 11640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell * distributed under the License is distributed on an "AS IS" BASIS, 12640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell * See the License for the specific language governing permissions and 14640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell * limitations under the License. 15640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell */ 16640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powellpackage com.android.internal.widget; 17640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 18425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powellimport com.android.internal.R; 193d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette 203d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viveretteimport android.util.TypedValue; 213d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viveretteimport android.view.ContextThemeWrapper; 2282d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viveretteimport android.view.MotionEvent; 23fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powellimport android.widget.ActionMenuPresenter; 24fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powellimport android.widget.ActionMenuView; 25640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 26640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powellimport android.animation.Animator; 27640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powellimport android.animation.AnimatorSet; 28640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powellimport android.animation.ObjectAnimator; 29640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powellimport android.animation.TimeInterpolator; 30640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powellimport android.content.Context; 31425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powellimport android.content.res.Configuration; 32425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powellimport android.content.res.TypedArray; 33640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powellimport android.util.AttributeSet; 34640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powellimport android.view.View; 35640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powellimport android.view.ViewGroup; 36640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powellimport android.view.animation.DecelerateInterpolator; 37640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 38640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powellpublic abstract class AbsActionBarView extends ViewGroup { 393d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette private static final TimeInterpolator sAlphaInterpolator = new DecelerateInterpolator(); 403d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette 413d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette private static final int FADE_DURATION = 200; 423d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette 433d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette protected final VisibilityAnimListener mVisAnimListener = new VisibilityAnimListener(); 443d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette 453d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette /** Context against which to inflate popup menus. */ 463d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette protected final Context mPopupContext; 473d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette 48640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell protected ActionMenuView mMenuView; 498d02deabac62c4a68a335a7b3141795466362b89Adam Powell protected ActionMenuPresenter mActionMenuPresenter; 50e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell protected ViewGroup mSplitView; 51a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell protected boolean mSplitActionBar; 52a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell protected boolean mSplitWhenNarrow; 53425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell protected int mContentHeight; 54640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 55640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell protected Animator mVisibilityAnim; 56640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 5782d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette private boolean mEatingTouch; 5882d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette private boolean mEatingHover; 5982d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette 60640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public AbsActionBarView(Context context) { 61d6479ec5eec13914f656f6be996d95fe1610fd57Alan Viverette this(context, null); 62640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 63640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 64640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public AbsActionBarView(Context context, AttributeSet attrs) { 65d6479ec5eec13914f656f6be996d95fe1610fd57Alan Viverette this(context, attrs, 0); 66640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 67640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 68617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public AbsActionBarView(Context context, AttributeSet attrs, int defStyleAttr) { 69617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette this(context, attrs, defStyleAttr, 0); 70617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette } 71617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette 72617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public AbsActionBarView( 73617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 74617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette super(context, attrs, defStyleAttr, defStyleRes); 753d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette 763d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette final TypedValue tv = new TypedValue(); 773d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette if (context.getTheme().resolveAttribute(R.attr.actionBarPopupTheme, tv, true) 783d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette && tv.resourceId != 0) { 793d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette mPopupContext = new ContextThemeWrapper(context, tv.resourceId); 803d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette } else { 813d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette mPopupContext = context; 823d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette } 83640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 84640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 85425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell @Override 86425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell protected void onConfigurationChanged(Configuration newConfig) { 87425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell super.onConfigurationChanged(newConfig); 88425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell 89425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell // Action bar can change size on configuration changes. 90425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell // Reread the desired height from the theme-specified style. 91425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.ActionBar, 92425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell com.android.internal.R.attr.actionBarStyle, 0); 93425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell setContentHeight(a.getLayoutDimension(R.styleable.ActionBar_height, 0)); 94425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell a.recycle(); 95a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell if (mSplitWhenNarrow) { 96e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell setSplitToolbar(getContext().getResources().getBoolean( 97a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell com.android.internal.R.bool.split_action_bar_is_narrow)); 98a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell } 99425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell if (mActionMenuPresenter != null) { 100425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell mActionMenuPresenter.onConfigurationChanged(newConfig); 101425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell } 102425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell } 103425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell 10482d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette @Override 10582d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette public boolean onTouchEvent(MotionEvent ev) { 10682d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette // ActionBarViews always eat touch events, but should still respect the touch event dispatch 10782d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette // contract. If the normal View implementation doesn't want the events, we'll just silently 10882d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette // eat the rest of the gesture without reporting the events to the default implementation 10982d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette // since that's what it expects. 11082d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette 11182d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette final int action = ev.getActionMasked(); 11282d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette if (action == MotionEvent.ACTION_DOWN) { 11382d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette mEatingTouch = false; 11482d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette } 11582d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette 11682d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette if (!mEatingTouch) { 11782d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette final boolean handled = super.onTouchEvent(ev); 11882d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette if (action == MotionEvent.ACTION_DOWN && !handled) { 11982d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette mEatingTouch = true; 12082d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette } 12182d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette } 12282d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette 12382d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { 12482d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette mEatingTouch = false; 12582d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette } 12682d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette 12782d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette return true; 12882d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette } 12982d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette 13082d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette @Override 13182d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette public boolean onHoverEvent(MotionEvent ev) { 13282d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette // Same deal as onTouchEvent() above. Eat all hover events, but still 13382d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette // respect the touch event dispatch contract. 13482d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette 13582d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette final int action = ev.getActionMasked(); 13682d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette if (action == MotionEvent.ACTION_HOVER_ENTER) { 13782d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette mEatingHover = false; 13882d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette } 13982d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette 14082d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette if (!mEatingHover) { 14182d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette final boolean handled = super.onHoverEvent(ev); 14282d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette if (action == MotionEvent.ACTION_HOVER_ENTER && !handled) { 14382d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette mEatingHover = true; 14482d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette } 14582d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette } 14682d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette 14782d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette if (action == MotionEvent.ACTION_HOVER_EXIT 14882d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette || action == MotionEvent.ACTION_CANCEL) { 14982d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette mEatingHover = false; 15082d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette } 15182d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette 15282d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette return true; 15382d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette } 15482d31d456e3b727bcf45a58710b4ea91f69c049aAlan Viverette 155a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell /** 156a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell * Sets whether the bar should be split right now, no questions asked. 157a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell * @param split true if the bar should split 158a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell */ 159e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell public void setSplitToolbar(boolean split) { 160a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell mSplitActionBar = split; 161a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell } 162a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell 163a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell /** 164a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell * Sets whether the bar should split if we enter a narrow screen configuration. 165a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell * @param splitWhenNarrow true if the bar should check to split after a config change 166a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell */ 167a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell public void setSplitWhenNarrow(boolean splitWhenNarrow) { 168a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell mSplitWhenNarrow = splitWhenNarrow; 169a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell } 170a05aba9c506cd12a753c53e060c289095c3477e9Adam Powell 171425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell public void setContentHeight(int height) { 172425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell mContentHeight = height; 173425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell requestLayout(); 174425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell } 175425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell 176425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell public int getContentHeight() { 177425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell return mContentHeight; 178425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell } 179425689eea2f4f208f29b944b4973981bdbeda9f5Adam Powell 180e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell public void setSplitView(ViewGroup splitView) { 181640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell mSplitView = splitView; 182640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 183640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 1849a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell /** 1859a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell * @return Current visibility or if animating, the visibility being animated to. 1869a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell */ 1879a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell public int getAnimatedVisibility() { 1889a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell if (mVisibilityAnim != null) { 1899a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell return mVisAnimListener.mFinalVisibility; 1909a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell } 1919a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell return getVisibility(); 1929a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell } 1939a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell 19494283533aba1b8c895728feb40462250a1ebecceDoris Liu public Animator setupAnimatorToVisibility(int visibility, long duration) { 195640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (mVisibilityAnim != null) { 196640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell mVisibilityAnim.cancel(); 197640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 19894283533aba1b8c895728feb40462250a1ebecceDoris Liu 199640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (visibility == VISIBLE) { 200640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (getVisibility() != VISIBLE) { 201640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell setAlpha(0); 202640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (mSplitView != null && mMenuView != null) { 203640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell mMenuView.setAlpha(0); 204640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 205640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 20694283533aba1b8c895728feb40462250a1ebecceDoris Liu ObjectAnimator anim = ObjectAnimator.ofFloat(this, View.ALPHA, 1); 20794283533aba1b8c895728feb40462250a1ebecceDoris Liu anim.setDuration(duration); 208640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell anim.setInterpolator(sAlphaInterpolator); 209640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (mSplitView != null && mMenuView != null) { 210640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell AnimatorSet set = new AnimatorSet(); 21194283533aba1b8c895728feb40462250a1ebecceDoris Liu ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, View.ALPHA, 1); 21294283533aba1b8c895728feb40462250a1ebecceDoris Liu splitAnim.setDuration(duration); 213640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell set.addListener(mVisAnimListener.withFinalVisibility(visibility)); 214640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell set.play(anim).with(splitAnim); 21594283533aba1b8c895728feb40462250a1ebecceDoris Liu return set; 216640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } else { 217640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); 21894283533aba1b8c895728feb40462250a1ebecceDoris Liu return anim; 219640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 220640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } else { 22194283533aba1b8c895728feb40462250a1ebecceDoris Liu ObjectAnimator anim = ObjectAnimator.ofFloat(this, View.ALPHA, 0); 22294283533aba1b8c895728feb40462250a1ebecceDoris Liu anim.setDuration(duration); 223640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell anim.setInterpolator(sAlphaInterpolator); 224640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (mSplitView != null && mMenuView != null) { 225640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell AnimatorSet set = new AnimatorSet(); 22694283533aba1b8c895728feb40462250a1ebecceDoris Liu ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, View.ALPHA, 0); 22794283533aba1b8c895728feb40462250a1ebecceDoris Liu splitAnim.setDuration(duration); 228640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell set.addListener(mVisAnimListener.withFinalVisibility(visibility)); 229640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell set.play(anim).with(splitAnim); 23094283533aba1b8c895728feb40462250a1ebecceDoris Liu return set; 231640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } else { 232640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); 23394283533aba1b8c895728feb40462250a1ebecceDoris Liu return anim; 234640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 235640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 236640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 237640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 23894283533aba1b8c895728feb40462250a1ebecceDoris Liu public void animateToVisibility(int visibility) { 23994283533aba1b8c895728feb40462250a1ebecceDoris Liu Animator anim = setupAnimatorToVisibility(visibility, FADE_DURATION); 24094283533aba1b8c895728feb40462250a1ebecceDoris Liu anim.start(); 24194283533aba1b8c895728feb40462250a1ebecceDoris Liu } 24294283533aba1b8c895728feb40462250a1ebecceDoris Liu 243640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell @Override 244640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public void setVisibility(int visibility) { 2459caeb145721238897809805f521bb5c8ef375c0fGeorge Mount if (visibility != getVisibility()) { 2469caeb145721238897809805f521bb5c8ef375c0fGeorge Mount if (mVisibilityAnim != null) { 2479caeb145721238897809805f521bb5c8ef375c0fGeorge Mount mVisibilityAnim.end(); 2489caeb145721238897809805f521bb5c8ef375c0fGeorge Mount } 2499caeb145721238897809805f521bb5c8ef375c0fGeorge Mount super.setVisibility(visibility); 250640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 251640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 252640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 253640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public boolean showOverflowMenu() { 2548d02deabac62c4a68a335a7b3141795466362b89Adam Powell if (mActionMenuPresenter != null) { 2558d02deabac62c4a68a335a7b3141795466362b89Adam Powell return mActionMenuPresenter.showOverflowMenu(); 256640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 257640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell return false; 258640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 259640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 260640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public void postShowOverflowMenu() { 261640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell post(new Runnable() { 262640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public void run() { 263640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell showOverflowMenu(); 264640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 265640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell }); 266640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 267640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 268640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public boolean hideOverflowMenu() { 2698d02deabac62c4a68a335a7b3141795466362b89Adam Powell if (mActionMenuPresenter != null) { 2708d02deabac62c4a68a335a7b3141795466362b89Adam Powell return mActionMenuPresenter.hideOverflowMenu(); 271640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 272640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell return false; 273640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 274640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 275640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public boolean isOverflowMenuShowing() { 2768d02deabac62c4a68a335a7b3141795466362b89Adam Powell if (mActionMenuPresenter != null) { 2778d02deabac62c4a68a335a7b3141795466362b89Adam Powell return mActionMenuPresenter.isOverflowMenuShowing(); 278640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 279640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell return false; 280640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 281640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 2825fcf5b9fd3ff6757090c6bd166b60c18eda0b3efAdam Powell public boolean isOverflowMenuShowPending() { 2835fcf5b9fd3ff6757090c6bd166b60c18eda0b3efAdam Powell if (mActionMenuPresenter != null) { 2845fcf5b9fd3ff6757090c6bd166b60c18eda0b3efAdam Powell return mActionMenuPresenter.isOverflowMenuShowPending(); 2855fcf5b9fd3ff6757090c6bd166b60c18eda0b3efAdam Powell } 2865fcf5b9fd3ff6757090c6bd166b60c18eda0b3efAdam Powell return false; 2875fcf5b9fd3ff6757090c6bd166b60c18eda0b3efAdam Powell } 2885fcf5b9fd3ff6757090c6bd166b60c18eda0b3efAdam Powell 289640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public boolean isOverflowReserved() { 2908d02deabac62c4a68a335a7b3141795466362b89Adam Powell return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved(); 291640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 292640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 293e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell public boolean canShowOverflowMenu() { 294e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell return isOverflowReserved() && getVisibility() == VISIBLE; 295e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell } 296e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell 297640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public void dismissPopupMenus() { 2988d02deabac62c4a68a335a7b3141795466362b89Adam Powell if (mActionMenuPresenter != null) { 2998d02deabac62c4a68a335a7b3141795466362b89Adam Powell mActionMenuPresenter.dismissPopupMenus(); 300640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 301640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 302640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 303640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell protected int measureChildView(View child, int availableWidth, int childSpecHeight, 304640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int spacing) { 305640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), 306640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell childSpecHeight); 307640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 308640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell availableWidth -= child.getMeasuredWidth(); 309640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell availableWidth -= spacing; 310640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 3115d4034a37e5ac3832b91388024f6eddf343cf3f6Adam Powell return Math.max(0, availableWidth); 312640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 313640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 314cf1ba0298c48ae56608ed556dc715eb69c54f9b9Fabrice Di Meglio static protected int next(int x, int val, boolean isRtl) { 315cf1ba0298c48ae56608ed556dc715eb69c54f9b9Fabrice Di Meglio return isRtl ? x - val : x + val; 316640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 317640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 318cf1ba0298c48ae56608ed556dc715eb69c54f9b9Fabrice Di Meglio protected int positionChild(View child, int x, int y, int contentHeight, boolean reverse) { 319640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int childWidth = child.getMeasuredWidth(); 320640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int childHeight = child.getMeasuredHeight(); 321640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell int childTop = y + (contentHeight - childHeight) / 2; 322640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 323cf1ba0298c48ae56608ed556dc715eb69c54f9b9Fabrice Di Meglio if (reverse) { 324cf1ba0298c48ae56608ed556dc715eb69c54f9b9Fabrice Di Meglio child.layout(x - childWidth, childTop, x, childTop + childHeight); 325cf1ba0298c48ae56608ed556dc715eb69c54f9b9Fabrice Di Meglio } else { 326cf1ba0298c48ae56608ed556dc715eb69c54f9b9Fabrice Di Meglio child.layout(x, childTop, x + childWidth, childTop + childHeight); 327cf1ba0298c48ae56608ed556dc715eb69c54f9b9Fabrice Di Meglio } 328640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 329cf1ba0298c48ae56608ed556dc715eb69c54f9b9Fabrice Di Meglio return (reverse ? -childWidth : childWidth); 330640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 331640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 332640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell protected class VisibilityAnimListener implements Animator.AnimatorListener { 333640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell private boolean mCanceled = false; 3349a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell int mFinalVisibility; 335640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 336640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public VisibilityAnimListener withFinalVisibility(int visibility) { 337640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell mFinalVisibility = visibility; 338640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell return this; 339640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 340640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 341640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell @Override 342640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public void onAnimationStart(Animator animation) { 343640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell setVisibility(VISIBLE); 344640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell mVisibilityAnim = animation; 345640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell mCanceled = false; 346640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 347640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 348640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell @Override 349640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public void onAnimationEnd(Animator animation) { 350640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (mCanceled) return; 351640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 352640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell mVisibilityAnim = null; 353640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell setVisibility(mFinalVisibility); 3549a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell if (mSplitView != null && mMenuView != null) { 3559a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell mMenuView.setVisibility(mFinalVisibility); 3569a5cc2810bbbcb0eab4579aa4131039820d92101Adam Powell } 357640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 358640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 359640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell @Override 360640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public void onAnimationCancel(Animator animation) { 361640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell mCanceled = true; 362640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 363640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 364640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell @Override 365640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public void onAnimationRepeat(Animator animation) { 366640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 367640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } 368640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell} 369