package com.liato.bankdroid; import android.content.Context; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.WindowManager; import android.widget.PopupWindow; /** * This class does most of the work of wrapping the {@link PopupWindow} so it's simpler to use. * * @author qberticus */ public class BetterPopupWindow { protected final ViewGroup parentView; protected final View anchor; private final PopupWindow window; private final WindowManager windowManager; private View root; private Drawable background = null; /** * Create a BetterPopupWindow * * @param anchor the view that the BetterPopupWindow will be displaying 'from' */ public BetterPopupWindow(ViewGroup parentView, View anchor) { this.anchor = anchor; this.parentView = parentView; this.window = new PopupWindow(anchor.getContext()); // when a touch even happens outside of the window // make the window go away this.window.setTouchInterceptor(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { BetterPopupWindow.this.window.dismiss(); return true; } return false; } }); this.windowManager = (WindowManager) this.anchor.getContext() .getSystemService(Context.WINDOW_SERVICE); onCreate(); } /** * Anything you want to have happen when created. Probably should create a view and setup the * event listeners on * child views. */ protected void onCreate() { } /** * In case there is stuff to do right before displaying. */ protected void onShow() { } private void preShow() { if (this.root == null) { throw new IllegalStateException( "setContentView was not called with a view to display."); } onShow(); if (this.background == null) { this.window.setBackgroundDrawable(new BitmapDrawable()); } else { this.window.setBackgroundDrawable(this.background); } // if using PopupWindow#setBackgroundDrawable this is the only values of the width and hight that make it work // otherwise you need to set the background of the root viewgroup // and set the popupwindow background to an empty BitmapDrawable this.window.setWidth(WindowManager.LayoutParams.FILL_PARENT); this.window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); this.window.setTouchable(true); this.window.setFocusable(true); this.window.setOutsideTouchable(true); this.window.setContentView(this.root); } public void setBackgroundDrawable(Drawable background) { this.background = background; } /** * Sets the content view. Probably should be called from {@link onCreate} * * @param root the view the popup will display */ public void setContentView(View root) { this.root = root; this.window.setContentView(root); } /** * Will inflate and set the view from a resource id */ public void setContentView(int layoutResID) { LayoutInflater inflator = (LayoutInflater) this.anchor.getContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.setContentView(inflator.inflate(layoutResID, null)); } /** * If you want to do anything when {@link dismiss} is called */ public void setOnDismissListener(PopupWindow.OnDismissListener listener) { this.window.setOnDismissListener(listener); } /** * Displays like a popdown menu from the anchor view */ public void showLikePopDownMenu() { this.showLikePopDownMenu(0, 0); } /** * Displays like a popdown menu from the anchor view. * * @param xOffset offset in X direction * @param yOffset offset in Y direction */ public void showLikePopDownMenu(int xOffset, int yOffset) { this.preShow(); this.window.setAnimationStyle(R.style.Animations_PopDownMenu); this.window.showAsDropDown(this.anchor, xOffset, yOffset); } /** * Displays like a QuickAction from the anchor view. */ public void showLikeQuickAction() { this.showLikeQuickAction(0, 0); } /** * Displays like a QuickAction from the anchor view. * * @param xOffset offset in the X direction * @param yOffset offset in the Y direction */ public void showLikeQuickAction(int xOffset, int yOffset) { this.preShow(); this.window.setAnimationStyle(R.style.Animations_GrowFromBottom); int[] location = new int[2]; this.anchor.getLocationOnScreen(location); Rect anchorRect = new Rect(location[0], location[1], location[0] + this.anchor.getWidth(), location[1] + this.anchor.getHeight()); this.root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); int rootWidth = this.root.getMeasuredWidth(); int rootHeight = this.root.getMeasuredHeight(); int screenWidth = this.windowManager.getDefaultDisplay().getWidth(); int screenHeight = this.windowManager.getDefaultDisplay().getHeight(); int xPos = ((screenWidth - rootWidth) / 2) + xOffset; int yPos = anchorRect.top - rootHeight + yOffset; // display on bottom if (rootHeight > anchorRect.top) { yPos = anchorRect.bottom - yOffset; this.window.setAnimationStyle(R.style.Animations_GrowFromTop); this.root.findViewById(R.id.layPopupCont).setBackgroundResource(R.drawable.popup_bg_up); } this.window.showAtLocation(this.anchor, Gravity.NO_GRAVITY, xPos, yPos); } public void dismiss() { this.window.dismiss(); } }