/** * 相对anchor view显示,适用 宽高不为match_parent * <p> * 注意:如果使用 VerticalGravity 和 HorizontalGravity 时,请确保使用之后 PopupWindow 没有超出屏幕边界, * 如果超出屏幕边界,VerticalGravity 和 HorizontalGravity 可能无效,从而达不到你想要的效果。 * * @param anchor * @param vertGravity 垂直方向的对齐方式 * @param horizGravity 水平方向的对齐方式 * @param x 水平方向的偏移 * @param y 垂直方向的偏移 */ public void showAtAnchorView(@NonNull View anchor, @VerticalGravity final int vertGravity, @HorizontalGravity int horizGravity, int x, int y) { if (mPopupWindow == null) { return; } mAnchorView = anchor; mOffsetX = x; mOffsetY = y; mVerticalGravity = vertGravity; mHorizontalGravity = horizGravity; isOnlyGetWH = false; //处理背景变暗 handleBackgroundDim(); final View contentView = getContentView(); addGlobalLayoutListener(contentView); contentView.measure(0, View.MeasureSpec.UNSPECIFIED); final int measuredW = contentView.getMeasuredWidth(); final int measuredH = contentView.getMeasuredHeight(); x = calculateX(anchor, horizGravity, measuredW, x); y = calculateY(anchor, vertGravity, measuredH, y); Log.i(TAG, "showAtAnchorView: w=" + measuredW + ",y=" + measuredH); PopupWindowCompat.showAsDropDown(mPopupWindow, anchor, x, y, Gravity.NO_GRAVITY); }
@RequiresApi(api = Build.VERSION_CODES.KITKAT) public void showAsDropDown(View anchor, int offsetX, int offsetY, int gravity) { if (mPopupWindow != null) { handleBackgroundDim(); mAnchorView = anchor; mOffsetX = offsetX; mOffsetY = offsetY; isOnlyGetWH = true; addGlobalLayoutListener(mPopupWindow.getContentView()); PopupWindowCompat.showAsDropDown(mPopupWindow, anchor, offsetX, offsetY, gravity); } }
public void setSupportOverlapAnchor(boolean overlapAnchor) { if (COMPAT_OVERLAP_ANCHOR) { this.mOverlapAnchor = overlapAnchor; } else { PopupWindowCompat.setOverlapAnchor(this, overlapAnchor); } }
/** * Shows a PopupWindow at the anchor view with given window height and list size. */ private void showPopupWindow(View button, int height, int listSize, boolean useDefaultInflater) { final Context context = button.getContext(); final ListView listView = new ListView(context); final BaseAdapter adapter; if (useDefaultInflater) { adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, android.R.id.text1, createSampleArray(listSize)); } else { adapter = new MyAdapter(button.getContext(), createSampleArray(listSize)); } listView.setAdapter(adapter); listView.setVerticalScrollBarEnabled(true); listView.setBackgroundColor(0xFFFFFF); final PopupWindow window = new PopupWindow(listView, ViewGroup.LayoutParams.WRAP_CONTENT, height, true); window.setBackgroundDrawable(context.getResources().getDrawable( android.R.drawable.editbox_background)); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { if (window.isShowing()) { window.dismiss(); } } }); PopupWindowCompat.showAsDropDown(window, button, 0, 0, Gravity.NO_GRAVITY); }
public boolean getSupportOverlapAnchor() { if (COMPAT_OVERLAP_ANCHOR) { return mOverlapAnchor; } else { return PopupWindowCompat.getOverlapAnchor(this); } }
public void setSupportOverlapAnchor(boolean flag) { if (COMPAT_OVERLAP_ANCHOR) { mOverlapAnchor = flag; return; } else { PopupWindowCompat.setOverlapAnchor(this, flag); return; } }
@Override public void onClick(View v) { if (clickListener != null) { clickListener.onClick(v); } //using 8dip on axisX offset to make dropdown view visually be at start of dropdown itself //using 4dip on axisY offset to make space between dropdown view and dropdown itself //all offsets are necessary because of the dialog_holo_light_frame to display correctly on screen(shadow was made by inset) int gravity; int axisXOffset; if (dropDownViewWidth + getX() > screenWidth) { gravity = Gravity.TOP | Gravity.END; axisXOffset = DimenUtils.dpToPixels(8); } else { gravity = Gravity.TOP | Gravity.START; axisXOffset = -DimenUtils.dpToPixels(8); } int axisYOffset = DimenUtils.dpToPixels(4); switch (expandDirection) { case UP: PopupWindowCompat.showAsDropDown(dropdownWindow, v, axisXOffset, -dropDownViewHeight - getMeasuredHeight() - axisYOffset * 3, gravity); break; case DOWN: PopupWindowCompat.showAsDropDown(dropdownWindow, v, axisXOffset, -axisYOffset, gravity); break; } setSelected(true); }
public void show(@NonNull View anchorView, @Nullable Callback callback) { this.callback = callback; popupWindowHost = new PopupWindow(this, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true); popupWindowHost.setBackgroundDrawable(new ColorDrawable(Color.BLACK)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { popupWindowHost.setElevation(getResources().getDimension(R.dimen.overflow_elevation)); } PopupWindowCompat.setOverlapAnchor(popupWindowHost, true); PopupWindowCompat.showAsDropDown(popupWindowHost, anchorView, 0, 0, Gravity.END); }
/** * Show at relative position to anchor View with translation. * @param anchor Anchor View * @param vertPos Vertical Position Flag * @param horizPos Horizontal Position Flag * @param x Translation X * @param y Translation Y * @param fitInScreen Automatically fit in screen or not */ public void showOnAnchor(@NonNull View anchor, @VerticalPosition int vertPos, @HorizontalPosition int horizPos, int x, int y, boolean fitInScreen) { setClippingEnabled(fitInScreen); View contentView = getContentView(); contentView.measure(makeDropDownMeasureSpec(getWidth()), makeDropDownMeasureSpec(getHeight())); final int measuredW = contentView.getMeasuredWidth(); final int measuredH = contentView.getMeasuredHeight(); if (!fitInScreen) { final int[] anchorLocation = new int[2]; anchor.getLocationInWindow(anchorLocation); x += anchorLocation[0]; y += anchorLocation[1] + anchor.getHeight(); } switch (vertPos) { case VerticalPosition.ABOVE: y -= measuredH + anchor.getHeight(); break; case VerticalPosition.ALIGN_BOTTOM: y -= measuredH; break; case VerticalPosition.CENTER: y -= anchor.getHeight()/2 + measuredH/2; break; case VerticalPosition.ALIGN_TOP: y -= anchor.getHeight(); break; case VerticalPosition.BELOW: // Default position. break; } switch (horizPos) { case HorizontalPosition.LEFT: x -= measuredW; break; case HorizontalPosition.ALIGN_RIGHT: x -= measuredW - anchor.getWidth(); break; case HorizontalPosition.CENTER: x += anchor.getWidth()/2 - measuredW/2; break; case HorizontalPosition.ALIGN_LEFT: // Default position. break; case HorizontalPosition.RIGHT: x += anchor.getWidth(); break; } if (fitInScreen) { PopupWindowCompat.showAsDropDown(this, anchor, x, y, Gravity.NO_GRAVITY); } else { showAtLocation(anchor, Gravity.NO_GRAVITY, x, y); } }
public boolean getSupportOverlapAnchor() { if (COMPAT_OVERLAP_ANCHOR) { return this.mOverlapAnchor; } return PopupWindowCompat.getOverlapAnchor(this); }
public AppCompatPopupWindow(Context paramContext, AttributeSet paramAttributeSet, int paramInt) { super(paramContext, paramAttributeSet, paramInt); TintTypedArray localTintTypedArray = TintTypedArray.obtainStyledAttributes$1a6c1917(paramContext, paramAttributeSet, R.styleable.PopupWindow, paramInt); boolean bool; if (localTintTypedArray.hasValue(R.styleable.PopupWindow_overlapAnchor)) { bool = localTintTypedArray.getBoolean(R.styleable.PopupWindow_overlapAnchor, false); if (!COMPAT_OVERLAP_ANCHOR) { break label136; } this.mOverlapAnchor = bool; } for (;;) { setBackgroundDrawable(localTintTypedArray.getDrawable(R.styleable.PopupWindow_android_popupBackground)); localTintTypedArray.mWrapped.recycle(); if (Build.VERSION.SDK_INT < 14) {} try { Field localField1 = PopupWindow.class.getDeclaredField("mAnchor"); localField1.setAccessible(true); Field localField2 = PopupWindow.class.getDeclaredField("mOnScrollChangedListener"); localField2.setAccessible(true); localField2.set(this, new ViewTreeObserver.OnScrollChangedListener() { public final void onScrollChanged() { try { WeakReference localWeakReference = (WeakReference)this.val$fieldAnchor.get(jdField_this); if (localWeakReference != null) { if (localWeakReference.get() == null) { return; } this.val$originalListener.onScrollChanged(); return; } } catch (IllegalAccessException localIllegalAccessException) {} } }); return; } catch (Exception localException) { label136: Log.d("AppCompatPopupWindow", "Exception while installing workaround OnScrollChangedListener", localException); } PopupWindowCompat.setOverlapAnchor(this, bool); } }