Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'android/3rd_party/HoloEverywhere/library/src/org/holoeverywhere/widget/PopupWindow.java')
-rw-r--r--android/3rd_party/HoloEverywhere/library/src/org/holoeverywhere/widget/PopupWindow.java844
1 files changed, 844 insertions, 0 deletions
diff --git a/android/3rd_party/HoloEverywhere/library/src/org/holoeverywhere/widget/PopupWindow.java b/android/3rd_party/HoloEverywhere/library/src/org/holoeverywhere/widget/PopupWindow.java
new file mode 100644
index 0000000000..6f30bf7137
--- /dev/null
+++ b/android/3rd_party/HoloEverywhere/library/src/org/holoeverywhere/widget/PopupWindow.java
@@ -0,0 +1,844 @@
+
+package org.holoeverywhere.widget;
+
+import java.lang.ref.WeakReference;
+
+import org.holoeverywhere.R;
+import org.holoeverywhere.drawable.DrawableCompat;
+import org.holoeverywhere.drawable.StateListDrawable;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+import android.os.IBinder;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnTouchListener;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnScrollChangedListener;
+import android.view.WindowManager;
+
+public class PopupWindow {
+ public interface OnDismissListener {
+ public void onDismiss();
+ }
+
+ private class PopupViewContainer extends FrameLayout {
+ public PopupViewContainer(Context context) {
+ super(context);
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+ if (getKeyDispatcherState() == null) {
+ return super.dispatchKeyEvent(event);
+ }
+
+ if (event.getAction() == KeyEvent.ACTION_DOWN
+ && event.getRepeatCount() == 0) {
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null) {
+ state.startTracking(event, this);
+ }
+ return true;
+ } else if (event.getAction() == KeyEvent.ACTION_UP) {
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null && state.isTracking(event) && !event.isCanceled()) {
+ dismiss();
+ return true;
+ }
+ }
+ return super.dispatchKeyEvent(event);
+ } else {
+ return super.dispatchKeyEvent(event);
+ }
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) {
+ return true;
+ }
+ return super.dispatchTouchEvent(ev);
+ }
+
+ @Override
+ protected int[] onCreateDrawableState(int extraSpace) {
+ if (mAboveAnchor) {
+ final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
+ View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET);
+ return drawableState;
+ } else {
+ return super.onCreateDrawableState(extraSpace);
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ final int x = (int) event.getX();
+ final int y = (int) event.getY();
+ if (event.getAction() == MotionEvent.ACTION_DOWN
+ && (x < 0 || x >= getWidth() || y < 0 || y >= getHeight())) {
+ dismiss();
+ return true;
+ } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
+ dismiss();
+ return true;
+ } else {
+ return super.onTouchEvent(event);
+ }
+ }
+
+ @Override
+ public void sendAccessibilityEvent(int eventType) {
+ if (mContentView != null) {
+ mContentView.sendAccessibilityEvent(eventType);
+ } else {
+ super.sendAccessibilityEvent(eventType);
+ }
+ }
+ }
+
+ private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] {
+ android.R.attr.state_above_anchor
+ };
+ public static final int INPUT_METHOD_FROM_FOCUSABLE = 0;
+ public static final int INPUT_METHOD_NEEDED = 1;
+ public static final int INPUT_METHOD_NOT_NEEDED = 2;
+ private boolean mAboveAnchor;
+ private Drawable mAboveAnchorBackgroundDrawable;
+ private boolean mAllowScrollingAnchorParent = true;
+ private WeakReference<View> mAnchor;
+ private int mAnchorXoff, mAnchorYoff;
+ private int mAnimationStyle = -1;
+ private Drawable mBackground;
+ private Drawable mBelowAnchorBackgroundDrawable;
+ private boolean mClippingEnabled = true;
+ private boolean mClipToScreen;
+ private View mContentView;
+ private Context mContext;
+ private int[] mDrawingLocation = new int[2];
+ private boolean mFocusable;
+ private int mHeight;
+ private int mHeightMode;
+ private boolean mIgnoreCheekPress = false;
+ private int mInputMethodMode = INPUT_METHOD_FROM_FOCUSABLE;
+ private boolean mIsDropdown;
+ private boolean mIsShowing;
+ private int mLastHeight;
+ private int mLastWidth;
+ private boolean mLayoutInScreen;
+ private boolean mLayoutInsetDecor = false;
+ private boolean mNotTouchModal;
+ private OnDismissListener mOnDismissListener;
+ private OnScrollChangedListener mOnScrollChangedListener =
+ new OnScrollChangedListener() {
+ @Override
+ public void onScrollChanged() {
+ View anchor = mAnchor != null ? mAnchor.get() : null;
+ if (anchor != null && mPopupView != null) {
+ WindowManager.LayoutParams p = (WindowManager.LayoutParams)
+ mPopupView.getLayoutParams();
+
+ updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff));
+ update(p.x, p.y, -1, -1, true);
+ }
+ }
+ };
+ private boolean mOutsideTouchable = false;
+ private int mPopupHeight;
+ private View mPopupView;
+ private int mPopupWidth;
+ private int[] mScreenLocation = new int[2];
+ private int mSoftInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;
+ private int mSplitTouchEnabled = -1;
+ private Rect mTempRect = new Rect();
+ private boolean mTouchable = true;
+ private OnTouchListener mTouchInterceptor;
+ private int mWidth;
+ private int mWidthMode;
+ private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
+ private WindowManager mWindowManager;
+
+ public PopupWindow() {
+ this(null, 0, 0);
+ }
+
+ public PopupWindow(Context context) {
+ this(context, null);
+ }
+
+ public PopupWindow(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.popupWindowStyle);
+ }
+
+ public PopupWindow(Context context, AttributeSet attrs, int defStyle) {
+ this(context, attrs, defStyle, 0);
+ }
+
+ public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ mContext = context;
+ mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PopupWindow, defStyleAttr,
+ defStyleRes);
+ mBackground = DrawableCompat
+ .getDrawable(a, R.styleable.PopupWindow_android_popupBackground);
+ final int animStyle = a.getResourceId(R.styleable.PopupWindow_android_popupAnimationStyle,
+ -1);
+ mAnimationStyle = animStyle == R.style.Holo_Animation_PopupWindow ? -1 : animStyle;
+ if (mBackground instanceof StateListDrawable) {
+ StateListDrawable background = (StateListDrawable) mBackground;
+ int aboveAnchorStateIndex = background.getStateDrawableIndex(ABOVE_ANCHOR_STATE_SET);
+ int count = background.getStateCount();
+ int belowAnchorStateIndex = -1;
+ for (int i = 0; i < count; i++) {
+ if (i != aboveAnchorStateIndex) {
+ belowAnchorStateIndex = i;
+ break;
+ }
+ }
+ if (aboveAnchorStateIndex != -1 && belowAnchorStateIndex != -1) {
+ mAboveAnchorBackgroundDrawable = background.getStateDrawable(aboveAnchorStateIndex);
+ mBelowAnchorBackgroundDrawable = background.getStateDrawable(belowAnchorStateIndex);
+ } else {
+ mBelowAnchorBackgroundDrawable = null;
+ mAboveAnchorBackgroundDrawable = null;
+ }
+ }
+ a.recycle();
+ }
+
+ public PopupWindow(int width, int height) {
+ this(null, width, height);
+ }
+
+ public PopupWindow(View contentView) {
+ this(contentView, 0, 0);
+ }
+
+ public PopupWindow(View contentView, int width, int height) {
+ this(contentView, width, height, false);
+ }
+
+ public PopupWindow(View contentView, int width, int height, boolean focusable) {
+ if (contentView != null) {
+ mContext = contentView.getContext();
+ mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+ }
+ setContentView(contentView);
+ setWidth(width);
+ setHeight(height);
+ setFocusable(focusable);
+ }
+
+ private int computeAnimationResource() {
+ if (mAnimationStyle == -1) {
+ if (mIsDropdown) {
+ return mAboveAnchor ? R.style.Holo_Animation_DropDownUp
+ : R.style.Holo_Animation_DropDownDown;
+ }
+ return 0;
+ }
+ return mAnimationStyle;
+ }
+
+ private int computeFlags(int curFlags) {
+ curFlags &= ~(
+ WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES |
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
+ WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
+ WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
+ WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
+ WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
+ WindowManager.LayoutParams.FLAG_SPLIT_TOUCH);
+ if (mIgnoreCheekPress) {
+ curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
+ }
+ if (!mFocusable) {
+ curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+ if (mInputMethodMode == INPUT_METHOD_NEEDED) {
+ curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+ }
+ } else if (mInputMethodMode == INPUT_METHOD_NOT_NEEDED) {
+ curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+ }
+ if (!mTouchable) {
+ curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+ }
+ if (mOutsideTouchable) {
+ curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
+ }
+ if (!mClippingEnabled) {
+ curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+ }
+ if (isSplitTouchEnabled()) {
+ curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
+ }
+ if (mLayoutInScreen) {
+ curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+ }
+ if (mLayoutInsetDecor) {
+ curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
+ }
+ if (mNotTouchModal) {
+ curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+ }
+ return curFlags;
+ }
+
+ private WindowManager.LayoutParams createPopupLayout(IBinder token) {
+ WindowManager.LayoutParams p = new WindowManager.LayoutParams();
+ p.gravity = Gravity.LEFT | Gravity.TOP;
+ p.width = mLastWidth = mWidth;
+ p.height = mLastHeight = mHeight;
+ if (mBackground != null) {
+ p.format = mBackground.getOpacity();
+ } else {
+ p.format = PixelFormat.TRANSLUCENT;
+ }
+ p.flags = computeFlags(p.flags);
+ p.type = mWindowLayoutType;
+ p.token = token;
+ p.softInputMode = mSoftInputMode;
+ p.setTitle("PopupWindow:" + Integer.toHexString(hashCode()));
+ return p;
+ }
+
+ public void dismiss() {
+ if (isShowing() && mPopupView != null) {
+ mIsShowing = false;
+ unregisterForScrollChanged();
+ try {
+ mWindowManager.removeViewImmediate(mPopupView);
+ } finally {
+ if (mPopupView != mContentView && mPopupView instanceof ViewGroup) {
+ ((ViewGroup) mPopupView).removeView(mContentView);
+ }
+ mPopupView = null;
+ if (mOnDismissListener != null) {
+ mOnDismissListener.onDismiss();
+ }
+ }
+ }
+ }
+
+ private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p,
+ int xoff, int yoff) {
+ final int anchorHeight = anchor.getHeight();
+ anchor.getLocationInWindow(mDrawingLocation);
+ p.x = mDrawingLocation[0] + xoff;
+ p.y = mDrawingLocation[1] + anchorHeight + yoff;
+ boolean onTop = false;
+ p.gravity = Gravity.LEFT | Gravity.TOP;
+ anchor.getLocationOnScreen(mScreenLocation);
+ final Rect displayFrame = new Rect();
+ anchor.getWindowVisibleDisplayFrame(displayFrame);
+ int screenY = mScreenLocation[1] + anchorHeight + yoff;
+ final View root = anchor.getRootView();
+ if (screenY + mPopupHeight > displayFrame.bottom ||
+ p.x + mPopupWidth - root.getWidth() > 0) {
+ if (mAllowScrollingAnchorParent) {
+ int scrollX = anchor.getScrollX();
+ int scrollY = anchor.getScrollY();
+ Rect r = new Rect(scrollX, scrollY, scrollX + mPopupWidth + xoff,
+ scrollY + mPopupHeight + anchor.getHeight() + yoff);
+ anchor.requestRectangleOnScreen(r, true);
+ }
+ anchor.getLocationInWindow(mDrawingLocation);
+ p.x = mDrawingLocation[0] + xoff;
+ p.y = mDrawingLocation[1] + anchor.getHeight() + yoff;
+ anchor.getLocationOnScreen(mScreenLocation);
+ onTop = displayFrame.bottom - mScreenLocation[1] - anchor.getHeight() - yoff <
+ mScreenLocation[1] - yoff - displayFrame.top;
+ if (onTop) {
+ p.gravity = Gravity.LEFT | Gravity.BOTTOM;
+ p.y = root.getHeight() - mDrawingLocation[1] + yoff;
+ } else {
+ p.y = mDrawingLocation[1] + anchor.getHeight() + yoff;
+ }
+ }
+ if (mClipToScreen) {
+ final int displayFrameWidth = displayFrame.right - displayFrame.left;
+ int right = p.x + p.width;
+ if (right > displayFrameWidth) {
+ p.x -= right - displayFrameWidth;
+ }
+ if (p.x < displayFrame.left) {
+ p.x = displayFrame.left;
+ p.width = Math.min(p.width, displayFrameWidth);
+ }
+ if (onTop) {
+ int popupTop = mScreenLocation[1] + yoff - mPopupHeight;
+ if (popupTop < 0) {
+ p.y += popupTop;
+ }
+ } else {
+ p.y = Math.max(p.y, displayFrame.top);
+ }
+ }
+ p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
+ return onTop;
+ }
+
+ public int getAnimationStyle() {
+ return mAnimationStyle;
+ }
+
+ public Drawable getBackground() {
+ return mBackground;
+ }
+
+ public View getContentView() {
+ return mContentView;
+ }
+
+ public int getHeight() {
+ return mHeight;
+ }
+
+ public int getInputMethodMode() {
+ return mInputMethodMode;
+
+ }
+
+ public int getMaxAvailableHeight(View anchor) {
+ return getMaxAvailableHeight(anchor, 0);
+ }
+
+ public int getMaxAvailableHeight(View anchor, int yOffset) {
+ return getMaxAvailableHeight(anchor, yOffset, false);
+ }
+
+ public int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) {
+ final Rect displayFrame = new Rect();
+ anchor.getWindowVisibleDisplayFrame(displayFrame);
+ final int[] anchorPos = mDrawingLocation;
+ anchor.getLocationOnScreen(anchorPos);
+ int bottomEdge = displayFrame.bottom;
+ if (ignoreBottomDecorations) {
+ Resources res = anchor.getContext().getResources();
+ bottomEdge = res.getDisplayMetrics().heightPixels;
+ }
+ final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
+ final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
+ int returnedHeight = Math.max(distanceToBottom, distanceToTop);
+ if (mBackground != null) {
+ mBackground.getPadding(mTempRect);
+ returnedHeight -= mTempRect.top + mTempRect.bottom;
+ }
+ return returnedHeight;
+ }
+
+ public int getSoftInputMode() {
+ return mSoftInputMode;
+ }
+
+ public int getWidth() {
+ return mWidth;
+ }
+
+ public int getWindowLayoutType() {
+ return mWindowLayoutType;
+ }
+
+ private void invokePopup(WindowManager.LayoutParams p) {
+ if (mContext != null) {
+ p.packageName = mContext.getPackageName();
+ }
+ if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) {
+ mPopupView.setFitsSystemWindows(mLayoutInsetDecor);
+ }
+ mWindowManager.addView(mPopupView, p);
+ }
+
+ public boolean isAboveAnchor() {
+ return mAboveAnchor;
+ }
+
+ public boolean isClippingEnabled() {
+ return mClippingEnabled;
+ }
+
+ public boolean isFocusable() {
+ return mFocusable;
+ }
+
+ public boolean isLayoutInScreenEnabled() {
+ return mLayoutInScreen;
+ }
+
+ public boolean isOutsideTouchable() {
+ return mOutsideTouchable;
+ }
+
+ public boolean isShowing() {
+ return mIsShowing;
+ }
+
+ public boolean isSplitTouchEnabled() {
+ if (mSplitTouchEnabled < 0 && mContext != null) {
+ return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB;
+ }
+ return mSplitTouchEnabled == 1;
+ }
+
+ public boolean isTouchable() {
+ return mTouchable;
+ }
+
+ @SuppressWarnings("deprecation")
+ private void preparePopup(WindowManager.LayoutParams p) {
+ if (mContentView == null || mContext == null || mWindowManager == null) {
+ throw new IllegalStateException("You must specify a valid content view by "
+ + "calling setContentView() before attempting to show the popup.");
+ }
+ if (mBackground != null) {
+ final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
+ int height = ViewGroup.LayoutParams.MATCH_PARENT;
+ if (layoutParams != null &&
+ layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
+ height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ }
+ PopupViewContainer popupViewContainer = new PopupViewContainer(mContext);
+ PopupViewContainer.LayoutParams listParams = new PopupViewContainer.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, height
+ );
+ popupViewContainer.setBackgroundDrawable(mBackground);
+ popupViewContainer.addView(mContentView, listParams);
+ mPopupView = popupViewContainer;
+ } else {
+ mPopupView = mContentView;
+ }
+ mPopupWidth = p.width;
+ mPopupHeight = p.height;
+ }
+
+ private void registerForScrollChanged(View anchor, int xoff, int yoff) {
+ unregisterForScrollChanged();
+ mAnchor = new WeakReference<View>(anchor);
+ ViewTreeObserver vto = anchor.getViewTreeObserver();
+ if (vto != null) {
+ vto.addOnScrollChangedListener(mOnScrollChangedListener);
+ }
+ mAnchorXoff = xoff;
+ mAnchorYoff = yoff;
+ }
+
+ void setAllowScrollingAnchorParent(boolean enabled) {
+ mAllowScrollingAnchorParent = enabled;
+ }
+
+ public void setAnimationStyle(int animationStyle) {
+ mAnimationStyle = animationStyle;
+ }
+
+ public void setBackgroundDrawable(Drawable background) {
+ mBackground = background;
+ }
+
+ public void setClippingEnabled(boolean enabled) {
+ mClippingEnabled = enabled;
+ }
+
+ public void setClipToScreenEnabled(boolean enabled) {
+ mClipToScreen = enabled;
+ setClippingEnabled(!enabled);
+ }
+
+ public void setContentView(View contentView) {
+ if (isShowing()) {
+ return;
+ }
+ mContentView = contentView;
+ if (mContext == null && mContentView != null) {
+ mContext = mContentView.getContext();
+ }
+ if (mWindowManager == null && mContext != null) {
+ mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+ }
+ }
+
+ public void setFocusable(boolean focusable) {
+ mFocusable = focusable;
+ }
+
+ public void setHeight(int height) {
+ mHeight = height;
+ }
+
+ public void setIgnoreCheekPress() {
+ mIgnoreCheekPress = true;
+ }
+
+ public void setInputMethodMode(int mode) {
+ mInputMethodMode = mode;
+ }
+
+ public void setLayoutInScreenEnabled(boolean enabled) {
+ mLayoutInScreen = enabled;
+ }
+
+ public void setLayoutInsetDecor(boolean enabled) {
+ mLayoutInsetDecor = enabled;
+ }
+
+ public void setOnDismissListener(OnDismissListener onDismissListener) {
+ mOnDismissListener = onDismissListener;
+ }
+
+ public void setOutsideTouchable(boolean touchable) {
+ mOutsideTouchable = touchable;
+ }
+
+ public void setSoftInputMode(int mode) {
+ mSoftInputMode = mode;
+ }
+
+ public void setSplitTouchEnabled(boolean enabled) {
+ mSplitTouchEnabled = enabled ? 1 : 0;
+ }
+
+ public void setTouchable(boolean touchable) {
+ mTouchable = touchable;
+ }
+
+ public void setTouchInterceptor(OnTouchListener l) {
+ mTouchInterceptor = l;
+ }
+
+ public void setTouchModal(boolean touchModal) {
+ mNotTouchModal = !touchModal;
+ }
+
+ public void setWidth(int width) {
+ mWidth = width;
+ }
+
+ public void setWindowLayoutMode(int widthSpec, int heightSpec) {
+ mWidthMode = widthSpec;
+ mHeightMode = heightSpec;
+ }
+
+ public void setWindowLayoutType(int layoutType) {
+ mWindowLayoutType = layoutType;
+ }
+
+ public void showAsDropDown(View anchor) {
+ showAsDropDown(anchor, 0, 0);
+ }
+
+ public void showAsDropDown(View anchor, int xoff, int yoff) {
+ if (isShowing() || mContentView == null) {
+ return;
+ }
+ registerForScrollChanged(anchor, xoff, yoff);
+ mIsShowing = true;
+ mIsDropdown = true;
+ WindowManager.LayoutParams p = createPopupLayout(anchor.getWindowToken());
+ preparePopup(p);
+ updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff));
+ if (mHeightMode < 0) {
+ p.height = mLastHeight = mHeightMode;
+ }
+ if (mWidthMode < 0) {
+ p.width = mLastWidth = mWidthMode;
+ }
+ p.windowAnimations = computeAnimationResource();
+ invokePopup(p);
+ }
+
+ public void showAtLocation(IBinder token, int gravity, int x, int y) {
+ if (isShowing() || mContentView == null) {
+ return;
+ }
+ unregisterForScrollChanged();
+ mIsShowing = true;
+ mIsDropdown = false;
+ WindowManager.LayoutParams p = createPopupLayout(token);
+ p.windowAnimations = computeAnimationResource();
+ preparePopup(p);
+ if (gravity == Gravity.NO_GRAVITY) {
+ gravity = Gravity.TOP | Gravity.LEFT;
+ }
+ p.gravity = gravity;
+ p.x = x;
+ p.y = y;
+ if (mHeightMode < 0) {
+ p.height = mLastHeight = mHeightMode;
+ }
+ if (mWidthMode < 0) {
+ p.width = mLastWidth = mWidthMode;
+ }
+ invokePopup(p);
+ }
+
+ public void showAtLocation(View parent, int gravity, int x, int y) {
+ showAtLocation(parent.getWindowToken(), gravity, x, y);
+ }
+
+ private void unregisterForScrollChanged() {
+ WeakReference<View> anchorRef = mAnchor;
+ View anchor = null;
+ if (anchorRef != null) {
+ anchor = anchorRef.get();
+ }
+ if (anchor != null) {
+ ViewTreeObserver vto = anchor.getViewTreeObserver();
+ vto.removeOnScrollChangedListener(mOnScrollChangedListener);
+ }
+ mAnchor = null;
+ }
+
+ public void update() {
+ if (!isShowing() || mContentView == null) {
+ return;
+ }
+ WindowManager.LayoutParams p = (WindowManager.LayoutParams)
+ mPopupView.getLayoutParams();
+ boolean update = false;
+ final int newAnim = computeAnimationResource();
+ if (newAnim != p.windowAnimations) {
+ p.windowAnimations = newAnim;
+ update = true;
+ }
+ final int newFlags = computeFlags(p.flags);
+ if (newFlags != p.flags) {
+ p.flags = newFlags;
+ update = true;
+ }
+ if (update) {
+ mWindowManager.updateViewLayout(mPopupView, p);
+ }
+ }
+
+ public void update(int width, int height) {
+ WindowManager.LayoutParams p = (WindowManager.LayoutParams)
+ mPopupView.getLayoutParams();
+ update(p.x, p.y, width, height, false);
+ }
+
+ public void update(int x, int y, int width, int height) {
+ update(x, y, width, height, false);
+ }
+
+ public void update(int x, int y, int width, int height, boolean force) {
+ if (width != -1) {
+ mLastWidth = width;
+ setWidth(width);
+ }
+ if (height != -1) {
+ mLastHeight = height;
+ setHeight(height);
+ }
+ if (!isShowing() || mContentView == null) {
+ return;
+ }
+ WindowManager.LayoutParams p = (WindowManager.LayoutParams) mPopupView.getLayoutParams();
+ boolean update = force;
+ final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth;
+ if (width != -1 && p.width != finalWidth) {
+ p.width = mLastWidth = finalWidth;
+ update = true;
+ }
+ final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight;
+ if (height != -1 && p.height != finalHeight) {
+ p.height = mLastHeight = finalHeight;
+ update = true;
+ }
+ if (p.x != x) {
+ p.x = x;
+ update = true;
+ }
+ if (p.y != y) {
+ p.y = y;
+ update = true;
+ }
+ final int newAnim = computeAnimationResource();
+ if (newAnim != p.windowAnimations) {
+ p.windowAnimations = newAnim;
+ update = true;
+ }
+ final int newFlags = computeFlags(p.flags);
+ if (newFlags != p.flags) {
+ p.flags = newFlags;
+ update = true;
+ }
+ if (update) {
+ mWindowManager.updateViewLayout(mPopupView, p);
+ }
+ }
+
+ private void update(View anchor, boolean updateLocation, int xoff, int yoff,
+ boolean updateDimension, int width, int height) {
+ if (!isShowing() || mContentView == null) {
+ return;
+ }
+ WeakReference<View> oldAnchor = mAnchor;
+ final boolean needsUpdate = updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff);
+ if (oldAnchor == null || oldAnchor.get() != anchor || needsUpdate && !mIsDropdown) {
+ registerForScrollChanged(anchor, xoff, yoff);
+ } else if (needsUpdate) {
+ mAnchorXoff = xoff;
+ mAnchorYoff = yoff;
+ }
+ WindowManager.LayoutParams p = (WindowManager.LayoutParams) mPopupView.getLayoutParams();
+ if (updateDimension) {
+ if (width == -1) {
+ width = mPopupWidth;
+ } else {
+ mPopupWidth = width;
+ }
+ if (height == -1) {
+ height = mPopupHeight;
+ } else {
+ mPopupHeight = height;
+ }
+ }
+ int x = p.x;
+ int y = p.y;
+ if (updateLocation) {
+ updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff));
+ } else {
+ updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff));
+ }
+ update(p.x, p.y, width, height, x != p.x || y != p.y);
+ }
+
+ public void update(View anchor, int width, int height) {
+ update(anchor, false, 0, 0, true, width, height);
+ }
+
+ public void update(View anchor, int xoff, int yoff, int width, int height) {
+ update(anchor, true, xoff, yoff, true, width, height);
+ }
+
+ @SuppressWarnings("deprecation")
+ private void updateAboveAnchor(boolean aboveAnchor) {
+ if (aboveAnchor != mAboveAnchor) {
+ mAboveAnchor = aboveAnchor;
+ if (mBackground != null) {
+ if (mAboveAnchorBackgroundDrawable != null) {
+ if (mAboveAnchor) {
+ mPopupView.setBackgroundDrawable(mAboveAnchorBackgroundDrawable);
+ } else {
+ mPopupView.setBackgroundDrawable(mBelowAnchorBackgroundDrawable);
+ }
+ } else {
+ mPopupView.refreshDrawableState();
+ }
+ }
+ }
+ }
+
+}