Source code
package android.support.v7.internal.widget;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.os.Build.VERSION;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPropertyAnimatorCompat;
import android.support.v4.view.ViewPropertyAnimatorListener;
import android.support.v7.appcompat.R;
import android.support.v7.widget.ActionMenuPresenter;
import android.support.v7.widget.ActionMenuView;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
abstract class AbsActionBarView extends ViewGroup {
private static final int FADE_DURATION = 200;
protected ActionMenuPresenter mActionMenuPresenter;
protected int mContentHeight;
private boolean mEatingHover;
private boolean mEatingTouch;
protected ActionMenuView mMenuView;
protected final Context mPopupContext;
protected final VisibilityAnimListener mVisAnimListener;
protected ViewPropertyAnimatorCompat mVisibilityAnim;
protected class VisibilityAnimListener implements ViewPropertyAnimatorListener {
private boolean mCanceled = false;
int mFinalVisibility;
protected VisibilityAnimListener() {
}
public VisibilityAnimListener withFinalVisibility(ViewPropertyAnimatorCompat animation, int visibility) {
AbsActionBarView.this.mVisibilityAnim = animation;
this.mFinalVisibility = visibility;
return this;
}
public void onAnimationStart(View view) {
super.setVisibility(0);
this.mCanceled = false;
}
public void onAnimationEnd(View view) {
if (!this.mCanceled) {
AbsActionBarView.this.mVisibilityAnim = null;
super.setVisibility(this.mFinalVisibility);
}
}
public void onAnimationCancel(View view) {
this.mCanceled = true;
}
}
AbsActionBarView(Context context) {
this(context, null);
}
AbsActionBarView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
AbsActionBarView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.mVisAnimListener = new VisibilityAnimListener();
TypedValue tv = new TypedValue();
if (!context.getTheme().resolveAttribute(R.attr.actionBarPopupTheme, tv, true) || tv.resourceId == 0) {
this.mPopupContext = context;
} else {
this.mPopupContext = new ContextThemeWrapper(context, tv.resourceId);
}
}
protected void onConfigurationChanged(Configuration newConfig) {
if (VERSION.SDK_INT >= 8) {
super.onConfigurationChanged(newConfig);
}
TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.ActionBar, R.attr.actionBarStyle, 0);
setContentHeight(a.getLayoutDimension(R.styleable.ActionBar_height, 0));
a.recycle();
if (this.mActionMenuPresenter != null) {
this.mActionMenuPresenter.onConfigurationChanged(newConfig);
}
}
public boolean onTouchEvent(MotionEvent ev) {
int action = MotionEventCompat.getActionMasked(ev);
if (action == 0) {
this.mEatingTouch = false;
}
if (!this.mEatingTouch) {
boolean handled = super.onTouchEvent(ev);
if (action == 0 && !handled) {
this.mEatingTouch = true;
}
}
if (action == 1 || action == 3) {
this.mEatingTouch = false;
}
return true;
}
public boolean onHoverEvent(MotionEvent ev) {
int action = MotionEventCompat.getActionMasked(ev);
if (action == 9) {
this.mEatingHover = false;
}
if (!this.mEatingHover) {
boolean handled = super.onHoverEvent(ev);
if (action == 9 && !handled) {
this.mEatingHover = true;
}
}
if (action == 10 || action == 3) {
this.mEatingHover = false;
}
return true;
}
public void setContentHeight(int height) {
this.mContentHeight = height;
requestLayout();
}
public int getContentHeight() {
return this.mContentHeight;
}
public int getAnimatedVisibility() {
if (this.mVisibilityAnim != null) {
return this.mVisAnimListener.mFinalVisibility;
}
return getVisibility();
}
public ViewPropertyAnimatorCompat setupAnimatorToVisibility(int visibility, long duration) {
if (this.mVisibilityAnim != null) {
this.mVisibilityAnim.cancel();
}
if (visibility == 0) {
if (getVisibility() != 0) {
ViewCompat.setAlpha(this, 0.0f);
}
ViewPropertyAnimatorCompat anim = ViewCompat.animate(this).alpha(1.0f);
anim.setDuration(duration);
anim.setListener(this.mVisAnimListener.withFinalVisibility(anim, visibility));
return anim;
}
anim = ViewCompat.animate(this).alpha(0.0f);
anim.setDuration(duration);
anim.setListener(this.mVisAnimListener.withFinalVisibility(anim, visibility));
return anim;
}
public void animateToVisibility(int visibility) {
setupAnimatorToVisibility(visibility, 200).start();
}
public void setVisibility(int visibility) {
if (visibility != getVisibility()) {
if (this.mVisibilityAnim != null) {
this.mVisibilityAnim.cancel();
}
super.setVisibility(visibility);
}
}
public boolean showOverflowMenu() {
if (this.mActionMenuPresenter != null) {
return this.mActionMenuPresenter.showOverflowMenu();
}
return false;
}
public void postShowOverflowMenu() {
post(new Runnable() {
public void run() {
AbsActionBarView.this.showOverflowMenu();
}
});
}
public boolean hideOverflowMenu() {
if (this.mActionMenuPresenter != null) {
return this.mActionMenuPresenter.hideOverflowMenu();
}
return false;
}
public boolean isOverflowMenuShowing() {
if (this.mActionMenuPresenter != null) {
return this.mActionMenuPresenter.isOverflowMenuShowing();
}
return false;
}
public boolean isOverflowMenuShowPending() {
if (this.mActionMenuPresenter != null) {
return this.mActionMenuPresenter.isOverflowMenuShowPending();
}
return false;
}
public boolean isOverflowReserved() {
return this.mActionMenuPresenter != null && this.mActionMenuPresenter.isOverflowReserved();
}
public boolean canShowOverflowMenu() {
return isOverflowReserved() && getVisibility() == 0;
}
public void dismissPopupMenus() {
if (this.mActionMenuPresenter != null) {
this.mActionMenuPresenter.dismissPopupMenus();
}
}
protected int measureChildView(View child, int availableWidth, int childSpecHeight, int spacing) {
child.measure(MeasureSpec.makeMeasureSpec(availableWidth, Integer.MIN_VALUE), childSpecHeight);
return Math.max(0, (availableWidth - child.getMeasuredWidth()) - spacing);
}
protected static int next(int x, int val, boolean isRtl) {
return isRtl ? x - val : x + val;
}
protected int positionChild(View child, int x, int y, int contentHeight, boolean reverse) {
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
int childTop = y + ((contentHeight - childHeight) / 2);
if (reverse) {
child.layout(x - childWidth, childTop, x, childTop + childHeight);
} else {
child.layout(x, childTop, x + childWidth, childTop + childHeight);
}
return reverse ? -childWidth : childWidth;
}
}