Skip to content

Instantly share code, notes, and snippets.

@carlonzo
Last active November 2, 2018 10:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlonzo/fbc81065ca00d7410483121d606ba8e2 to your computer and use it in GitHub Desktop.
Save carlonzo/fbc81065ca00d7410483121d606ba8e2 to your computer and use it in GitHub Desktop.
Centered Window Android. It will align the contentView at the center of the anchor. It has a addOnGlobalLayoutListener to refresh the position when the size of the contentview changes
public class PopupHighlightItems {
private WindowManager windowManager;
private final View contentView;
private WeakReference<View> anchor;
private int direction = Gravity.TOP;
private boolean isShowing = false;
private WindowManager.LayoutParams layoutParams;
public PopupHighlightItems(Context context, View contentView, OnClickListener onClickListener) {
this.windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
this.contentView = contentView;
createLayoutParams(contentView);
contentView.setElevation(context.getResources().getDimension(R.dimen.elevation_medium));
contentView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override public void onGlobalLayout() {
boolean changed = calculatePosition();
if (isShowing && changed) {
windowManager.updateViewLayout(contentView, layoutParams);
}
}
});
contentView.setOnClickListener(onClickListener);
}
private void createLayoutParams(View contentView) {
this.layoutParams = new WindowManager.LayoutParams();
LayoutParams contentViewLayoutParams = contentView.getLayoutParams();
if (contentViewLayoutParams != null) {
layoutParams.width = contentViewLayoutParams.width;
layoutParams.height = contentViewLayoutParams.height;
} else {
layoutParams.width = LayoutParams.WRAP_CONTENT;
layoutParams.height = LayoutParams.WRAP_CONTENT;
}
layoutParams.flags = (
WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES |
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
WindowManager.LayoutParams.FLAG_SPLIT_TOUCH);
layoutParams.format = PixelFormat.TRANSLUCENT;
layoutParams.gravity = Gravity.START | Gravity.TOP;
layoutParams.windowAnimations = 0;
layoutParams.setTitle("PopupHighlightItems:" + Integer.toHexString(hashCode()));
layoutParams.packageName = contentView.getContext().getPackageName();
}
private boolean calculatePosition() {
int x = layoutParams.x;
int y = layoutParams.y;
View anchor = this.anchor.get();
final int[] anchorLocation = new int[2];
anchor.getLocationInWindow(anchorLocation);
Rect displayFrame = new Rect();
anchor.getWindowVisibleDisplayFrame(displayFrame);
layoutParams.x = anchorLocation[0] - displayFrame.left + anchor.getWidth() / 2 - contentView.getWidth() / 2;
layoutParams.y = anchorLocation[1] - displayFrame.top;
if (direction == Gravity.BOTTOM) {
layoutParams.y += anchor.getHeight() - contentView.getHeight();
}
return layoutParams.x != x || layoutParams.y != y;
}
public void show(View anchor, int direction) {
this.anchor = new WeakReference<>(anchor);
this.direction = direction; // TOP or BOTTOM
calculatePosition();
windowManager.addView(contentView, layoutParams);
isShowing = true;
}
public void dismiss() {
if (isShowing) {
windowManager.removeView(contentView);
isShowing = false;
}
}
public boolean isShowing() {
return isShowing;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment