Android:自定义Popup Windows


原文:http://www.d-android.com/developer/thread-25407-1-1.html

PopupWindow在android.widget包下,弹出窗口的形式展示。官方文档对该控件的描述是:“一个弹出窗口控件,可以用来显示任意视图(View),而且会浮动在当前 活动(activity)的顶部”。PopupWindow可以让我们实现多种自定义控件,例如:menu、alertdialog等弹窗似的View。

UI开发第三篇——popupwindow 中简单介绍了一些简单方法,这一篇分享一个实例。看效果:

            

0_13200385887DGQ.gif 0_1320038611Mm9J.gif 0_1320038600Es8h.gif



     



实现中使用的  PopupWindow。这里做了简单封装,其中有三个类组成:PopuItem、PopuJar、PopupWindows。
0_1320038621lkZr.gif 0_13200386304j46.gif

view plain
public class PopuItem {  
    private Drawable icon;  
    private Bitmap thumb;  
    private String title;  
    private int actionId = -1;  
    private boolean selected;  
    private boolean sticky;  
      
    /**
     * Constructor
     *  
     * @param actionId  Action id for case statements
     * @param title     Title
     * @param icon      Icon to use
     */  
    public PopuItem(int actionId, String title, Drawable icon) {  
        this.title = title;  
        this.icon = icon;  
        this.actionId = actionId;  
    }  
      
    /**
     * Constructor
     */  
    public PopuItem() {  
        this(-1, null, null);  
    }  
      
    /**
     * Constructor
     *  
     * @param actionId  Action id of the item
     * @param title     Text to show for the item
     */  
    public PopuItem(int actionId, String title) {  
        this(actionId, title, null);  
    }  
      
    /**
     * Constructor
     *  
     * @param icon {@link Drawable} action icon
     */  
    public PopuItem(Drawable icon) {  
        this(-1, null, icon);  
    }  
      
    /**
     * Constructor
     *  
     * @param actionId  Action ID of item
     * @param icon      {@link Drawable} action icon
     */  
    public PopuItem(int actionId, Drawable icon) {  
        this(actionId, null, icon);  
    }  
      
    /**
     * Set action title
     *  
     * @param title action title
     */  
    public void setTitle(String title) {  
        this.title = title;  
    }  
      
    /**
     * Get action title
     *  
     * @return action title
     */  
    public String getTitle() {  
        return this.title;  
    }  
      
    /**
     * Set action icon
     *  
     * @param icon {@link Drawable} action icon
     */  
    public void setIcon(Drawable icon) {  
        this.icon = icon;  
    }  
      
    /**
     * Get action icon
     * @return  {@link Drawable} action icon
     */  
    public Drawable getIcon() {  
        return this.icon;  
    }  
      
     /**
     * Set action id
     *  
     * @param actionId  Action id for this action
     */  
    public void setActionId(int actionId) {  
        this.actionId = actionId;  
    }  
      
    /**
     * @return  Our action id
     */  
    public int getActionId() {  
        return actionId;  
    }  
      
    /**
     * Set sticky status of button
     *  
     * @param sticky  true for sticky, pop up sends event but does not disappear
     */  
    public void setSticky(boolean sticky) {  
        this.sticky = sticky;  
    }  
      
    /**
     * @return  true if button is sticky, menu stays visible after press
     */  
    public boolean isSticky() {  
        return sticky;  
    }  
      
    /**
     * Set selected flag;
     *  
     * @param selected Flag to indicate the item is selected
     */  
    public void setSelected(boolean selected) {  
        this.selected = selected;  
    }  
      
    /**
     * Check if item is selected
     *  
     * @return true or false
     */  
    public boolean isSelected() {  
        return this.selected;  
    }  
  
    /**
     * Set thumb
     *  
     * @param thumb Thumb image
     */  
    public void setThumb(Bitmap thumb) {  
        this.thumb = thumb;  
    }  
      
    /**
     * Get thumb image
     *  
     * @return Thumb image
     */  
    public Bitmap getThumb() {  
        return this.thumb;  
    }  
}  



view plain
public class PopuJar extends PopupWindows implements OnDismissListener {  
    private View mRootView;  
    private ImageView mArrowUp;  
    private ImageView mArrowDown;  
    private LayoutInflater mInflater;  
    private ViewGroup mTrack;  
    private ScrollView mScroller;  
    private OnPopuItemClickListener mItemClickListener;  
    private OnDismissListener mDismissListener;  
      
    private List<PopuItem> PopuItems = new ArrayList<PopuItem>();  
      
    private boolean mDidAction;  
      
    private int mChildPos;  
    private int mInsertPos;  
    private int mAnimStyle;  
    private int mOrientation;  
    private int rootWidth=0;  
      
    public static final int HORIZONTAL = 0;  
    public static final int VERTICAL = 1;  
      
    public static final int ANIM_GROW_FROM_LEFT = 1;  
    public static final int ANIM_GROW_FROM_RIGHT = 2;  
    public static final int ANIM_GROW_FROM_CENTER = 3;  
    public static final int ANIM_REFLECT = 4;  
    public static final int ANIM_AUTO = 5;  
      
    /**
     * Constructor for default vertical layout
     *  
     * @param context  Context
     */  
    public PopuJar(Context context) {  
        this(context, VERTICAL);  
    }  
  
    /**
     * Constructor allowing orientation override
     *  
     * @param context    Context
     * @param orientation Layout orientation, can be vartical or horizontal
     */  
    public PopuJar(Context context, int orientation) {  
        super(context);  
         
        mOrientation = orientation;  
         
        mInflater    = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  
        if (mOrientation == HORIZONTAL) {  
            setRootViewId(R.layout.popup_horizontal);  
        } else {  
            setRootViewId(R.layout.popup_vertical);  
        }  
  
        mAnimStyle  = ANIM_AUTO;  
        mChildPos   = 0;  
    }  
  
    /**
     * Get action item at an index
     *  
     * @param index  Index of item (position from callback)
     *  
     * @return  Action Item at the position
     */  
    public PopuItem getPopuItem(int index) {  
        return PopuItems.get(index);  
    }  
      
    /**
     * Set root view.
     *  
     * @param id Layout resource id
     */  
    public void setRootViewId(int id) {  
        mRootView   = (ViewGroup) mInflater.inflate(id, null);  
        mTrack      = (ViewGroup) mRootView.findViewById(R.id.tracks);  
  
        mArrowDown  = (ImageView) mRootView.findViewById(R.id.arrow_down);  
        mArrowUp    = (ImageView) mRootView.findViewById(R.id.arrow_up);  
  
        mScroller   = (ScrollView) mRootView.findViewById(R.id.scroller);  
         
        //This was previously defined on show() method, moved here to prevent force close that occured  
        //when tapping fastly on a view to show quickaction dialog.  
        //Thanx to zammbi (github.com/zammbi)  
        mRootView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));  
         
        setContentView(mRootView);  
    }  
      
    /**
     * Set animation style
     *  
     * @param mAnimStyle animation style, default is set to ANIM_AUTO
     */  
    public void setAnimStyle(int mAnimStyle) {  
        this.mAnimStyle = mAnimStyle;  
    }  
      
    /**
     * Set listener for action item clicked.
     *  
     * @param listener Listener
     */  
    public void setOnPopuItemClickListener(OnPopuItemClickListener listener) {  
        mItemClickListener = listener;  
    }  
      
    /**
     * Add action item
     *  
     * @param action  {@link PopuItem}
     */  
    public void addPopuItem(PopuItem action) {  
        PopuItems.add(action);  
         
        String title    = action.getTitle();  
        Drawable icon   = action.getIcon();  
         
        View container;  
         
        if (mOrientation == HORIZONTAL) {  
            container = mInflater.inflate(R.layout.action_item_horizontal, null);  
        } else {  
            container = mInflater.inflate(R.layout.action_item_vertical, null);  
        }  
         
        ImageView img   = (ImageView) container.findViewById(R.id.iv_icon);  
        TextView text   = (TextView) container.findViewById(R.id.tv_title);  
         
        if (icon != null) {  
            img.setImageDrawable(icon);  
        } else {  
            img.setVisibility(View.GONE);  
        }  
         
        if (title != null) {  
            text.setText(title);  
        } else {  
            text.setVisibility(View.GONE);  
        }  
         
        final int pos       =  mChildPos;  
        final int actionId  = action.getActionId();  
         
        container.setOnClickListener(new OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                if (mItemClickListener != null) {  
                    mItemClickListener.onItemClick(PopuJar.this, pos, actionId);  
                }  
                  
                if (!getPopuItem(pos).isSticky()) {   
                    mDidAction = true;  
                     
                    dismiss();  
                }  
            }  
        });  
         
        container.setFocusable(true);  
        container.setClickable(true);  
               
        if (mOrientation == HORIZONTAL && mChildPos != 0) {  
            View separator = mInflater.inflate(R.layout.horiz_separator, null);  
              
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);  
              
            separator.setLayoutParams(params);  
            separator.setPadding(5, 0, 5, 0);  
              
            mTrack.addView(separator, mInsertPos);  
              
            mInsertPos++;  
        }  
         
        mTrack.addView(container, mInsertPos);  
         
        mChildPos++;  
        mInsertPos++;  
    }  
      
    /**
     * Show quickaction popup. Popup is automatically positioned, on top or bottom of anchor view.
     *  
     */  
    public void show (View anchor) {  
        preShow();  
         
        int xPos, yPos, arrowPos;  
         
        mDidAction          = false;  
         
        int[] location      = new int[2];  
      
        anchor.getLocationOnScreen(location);  
  
        Rect anchorRect     = new Rect(location[0], location[1], location[0] + anchor.getWidth(), location[1]   
                            + anchor.getHeight());  
  
        //mRootView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));  
         
        mRootView.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
      
        int rootHeight      = mRootView.getMeasuredHeight();  
         
        if (rootWidth == 0) {  
            rootWidth       = mRootView.getMeasuredWidth();  
        }  
         
        int screenWidth     = mWindowManager.getDefaultDisplay().getWidth();  
        int screenHeight    = mWindowManager.getDefaultDisplay().getHeight();  
         
        //automatically get X coord of popup (top left)  
        if ((anchorRect.left + rootWidth) > screenWidth) {  
            xPos        = anchorRect.left - (rootWidth-anchor.getWidth());            
            xPos        = (xPos < 0) ? 0 : xPos;  
              
            arrowPos    = anchorRect.centerX()-xPos;  
              
        } else {  
            if (anchor.getWidth() > rootWidth) {  
                xPos = anchorRect.centerX() - (rootWidth/2);  
            } else {  
                xPos = anchorRect.left;  
            }  
              
            arrowPos = anchorRect.centerX()-xPos;  
        }  
         
        int dyTop           = anchorRect.top;  
        int dyBottom        = screenHeight - anchorRect.bottom;  
  
        boolean onTop       = (dyTop > dyBottom) ? true : false;  
  
        if (onTop) {  
            if (rootHeight > dyTop) {  
                yPos            = 15;  
                LayoutParams l  = mScroller.getLayoutParams();  
                l.height        = dyTop - anchor.getHeight();  
            } else {  
                yPos = anchorRect.top - rootHeight;  
            }  
        } else {  
            yPos = anchorRect.bottom;  
              
            if (rootHeight > dyBottom) {   
                LayoutParams l  = mScroller.getLayoutParams();  
                l.height        = dyBottom;  
            }  
        }  
         
        showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up), arrowPos);  
         
        setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);  
         
        mWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, xPos, yPos);  
    }  
      
    /**
     * Set animation style
     *  
     * @param screenWidth screen width
     * @param requestedX distance from left edge
     * @param onTop flag to indicate where the popup should be displayed. Set TRUE if displayed on top of anchor view
     *        and vice versa
     */  
    private void setAnimationStyle(int screenWidth, int requestedX, boolean onTop) {  
        int arrowPos = requestedX - mArrowUp.getMeasuredWidth()/2;  
  
        switch (mAnimStyle) {  
        case ANIM_GROW_FROM_LEFT:  
            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);  
            break;  
                     
        case ANIM_GROW_FROM_RIGHT:  
            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);  
            break;  
                     
        case ANIM_GROW_FROM_CENTER:  
            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);  
        break;  
              
        case ANIM_REFLECT:  
            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect : R.style.Animations_PopDownMenu_Reflect);  
        break;  
         
        case ANIM_AUTO:  
            if (arrowPos <= screenWidth/4) {  
                mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);  
            } else if (arrowPos > screenWidth/4 && arrowPos < 3 * (screenWidth/4)) {  
                mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);  
            } else {  
                mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);  
            }  
                     
            break;  
        }  
    }  
      
    /**
     * Show arrow
     *  
     * @param whichArrow arrow type resource id
     * @param requestedX distance from left screen
     */  
    private void showArrow(int whichArrow, int requestedX) {  
        final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp : mArrowDown;  
        final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown : mArrowUp;  
  
        final int arrowWidth = mArrowUp.getMeasuredWidth();  
  
        showArrow.setVisibility(View.VISIBLE);  
         
        ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams)showArrow.getLayoutParams();  
         
        param.leftMargin = requestedX - arrowWidth / 2;  
         
        hideArrow.setVisibility(View.INVISIBLE);  
    }  
      
    /**
     * Set listener for window dismissed. This listener will only be fired if the quicakction dialog is dismissed
     * by clicking outside the dialog or clicking on sticky item.
     */  
    public void setOnDismissListener(PopuJar.OnDismissListener listener) {  
        setOnDismissListener(this);  
         
        mDismissListener = listener;  
    }  
      
    @Override  
    public void onDismiss() {  
        if (!mDidAction && mDismissListener != null) {  
            mDismissListener.onDismiss();  
        }  
    }  
      
    /**
     * Listener for item click
     *
     */  
    public interface OnPopuItemClickListener {  
        public abstract void onItemClick(PopuJar source, int pos, int actionId);  
    }  
      
    /**
     * Listener for window dismiss
     *  
     */  
    public interface OnDismissListener {  
        public abstract void onDismiss();  
    }  
}  





view plain
public class PopupWindows {  
    protected Context mContext;  
    protected PopupWindow mWindow;  
    protected View mRootView;  
    protected Drawable mBackground = null;  
    protected WindowManager mWindowManager;  
      
    /**
     * Constructor.
     *  
     * @param context Context
     */  
    public PopupWindows(Context context) {  
        mContext    = context;  
        mWindow     = new PopupWindow(context);  
  
        mWindow.setTouchInterceptor(new OnTouchListener() {  
            @Override  
            public boolean onTouch(View v, MotionEvent event) {  
                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {  
                    mWindow.dismiss();  
                     
                    return true;  
                }  
                  
                return false;  
            }  
        });  
  
        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);  
    }  
      
    /**
     * On dismiss
     */  
    protected void onDismiss() {         
    }  
      
    /**
     * On show
     */  
    protected void onShow() {         
    }  
  
    /**
     * On pre show
     */  
    protected void preShow() {  
        if (mRootView == null)   
            throw new IllegalStateException("setContentView was not called with a view to display.");  
      
        onShow();  
  
        if (mBackground == null)   
            mWindow.setBackgroundDrawable(new BitmapDrawable());  
        else   
            mWindow.setBackgroundDrawable(mBackground);  
  
        mWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);  
        mWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);  
        mWindow.setTouchable(true);  
        mWindow.setFocusable(true);  
        mWindow.setOutsideTouchable(true);  
  
        mWindow.setContentView(mRootView);  
    }  
  
    /**
     * Set background drawable.
     *  
     * @param background Background drawable
     */  
    public void setBackgroundDrawable(Drawable background) {  
        mBackground = background;  
    }  
  
    /**
     * Set content view.
     *  
     * @param root Root view
     */  
    public void setContentView(View root) {  
        mRootView = root;  
         
        mWindow.setContentView(root);  
    }  
  
    /**
     * Set content view.
     *  
     * @param layoutResID Resource id
     */  
    public void setContentView(int layoutResID) {  
        LayoutInflater inflator = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
         
        setContentView(inflator.inflate(layoutResID, null));  
    }  
  
    /**
     * Set listener on window dismissed.
     *  
     * @param listener
     */  
    public void setOnDismissListener(PopupWindow.OnDismissListener listener) {  
        mWindow.setOnDismissListener(listener);   
    }  
  
    /**
     * Dismiss the popup window.
     */  
    public void dismiss() {  
        mWindow.dismiss();  
    }  
}  




Popu调用时在onCreate使用如下:

   

view plain
PopuItem userItem   = new PopuItem(ID_USER, "用户", getResources().getDrawable(R.drawable.child_image));  
PopuItem grounpItem     = new PopuItem(ID_GROUNP, "群组", getResources().getDrawable(R.drawable.user_group));   
      //use setSticky(true) to disable PopuJar dialog being dismissed after an item is clicked  
      userItem.setSticky(true);  
  
//create PopuJar. Use PopuJar.VERTICAL or PopuJar.HORIZONTAL param to define layout   
final PopuJar mPopu = new PopuJar(this, PopuJar.VERTICAL);  
  
//add action items into PopuJar  
mPopu.addPopuItem(userItem);  
mPopu.addPopuItem(grounpItem);  


显示popu:

view plain
mPopu.show(v); //v表示显示在那个view下面  

参考:

http://code.google.com/p/simple-quickactions/

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值