popupWindow 实现菜单

本博客是查看以下俩篇完成的:
http://www.cnblogs.com/sw926/p/3230659.html
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0702/1627.html

最近开发做了一个菜单,我是使用的popupWindow ,总结下,以免自己忘了。

public PopupWindow(View contentView, int width, int height, boolean focusable)

contentView为要显示的view,width和height为宽和高,,focusable为是否可以获得焦点

其中,高和宽必须设置,不然显示不出来,因为这个没有默认的布局文件,

其中,width 和 height 可以使用 WRAP_CONTENT,或者match_parent 来指定,也可以
使用px值,是指PopupWindow的大小,也就是contentview的大小,注意popupwindow根据这个大小显示你的View,如果你的View本身是从xml得到的,那么xml的第一层view的大小属性将被忽略。相当于popupWindow的width和height属性直接和第一层View相对应。

显示它:
showAsDropDown(View anchor):相对某个控件的位置(正左下方),无偏移
showAsDropDown(View anchor, int xoff, int yoff):相对某个控件的位置,有偏移
showAtLocation(View parent, int gravity, int x, int y):相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移
其实我发现showAtLocation的parent参数可以很随意,只要是activity中的view都可以。

处理焦点:
setFocusable设置PopupWindow的焦点,一般资料对此的解释都是:是否让Popupwindow可以点击但是这揭示了本质却与直观现象不符。实际上,
如果:
setFocusable(true);
则PopUpWindow本身可以看作一个类似于模态对话框的东西(但有区别),PopupWindow弹出后,所有的触屏和物理按键都有PopupWindows处理。其他任何事件的响应都必须发生在PopupWindow消失之后, (home 等系统层面的事件除外)。比如这样一个PopupWindow出现的时候,按back键首先是让PopupWindow消失,第二次按才是退出activity,准确的说是想退出activity你得首先让PopupWindow消失,因为不并是任何情况下按back PopupWindow都会消失,必须在PopupWindow设置了背景的情况下 。

如果PopupWindow中有Editor的话,focusable要为true。

而setFocusable(false);
则PopUpWindow只是一个浮现在当前界面上的view而已,不影响当前界面的任何操作。
是一个“没有存在感”的东西。一般情况下setFocusable(true);

点击空白处消失:
关于PopupWindow最搞笑的地方是setOutsideTouchable方法,原本以为如果你setOutsideTouchable(true)则点击PopupWindow之外的地方PopupWindow会消失,其实这玩意儿好像一点用都没有。
要让点击PopupWindow之外的地方PopupWindow消失你需要调用
setBackgroundDrawable(new BitmapDrawable());

设置背景,为了不影响样式,这个背景是空的。还可以这样写,觉得这样要保险些:

setBackgroundDrawable(new ColorDrawable(0x00000000));

背景不为空但是完全透明。如此设置还能让PopupWindow在点击back的时候消失。其实一直觉得很奇怪,不明白为什么一个背景会影响点击事件,只知道这样用可行。

后来在评论中有人回答了此问题:
如果有背景,则会在contentView外面包一层PopupViewContainer之后作为mPopupView,如果没有背景,则直接用contentView作为mPopupView。
而这个PopupViewContainer是一个内部私有类,它继承了FrameLayout,在其中重写了Key和Touch事件的分发处理
详情见:http://www.cnblogs.com/mengdd/p/3569127.html

最后,附上写的菜单的代码:

public class MenuWindow {

private PopupWindow popupWindow;
private List<String> mList = new ArrayList<>();
private OnItemClickListener onItemClickListener;

public void createWindow(Context context, List<String> item){
    mList.addAll(item);
    LayoutInflater inflater = LayoutInflater.from(context);
    View view = inflater.inflate(R.layout.window_meun, null);
    RecyclerView mRecyclerView = (RecyclerView) view.findViewById(R.id.recycleView);
    popupWindow = new PopupWindow(view, DisUtils.dp2px(context,120), ViewGroup.LayoutParams.WRAP_CONTENT,true);
    popupWindow.setOutsideTouchable(true);
    popupWindow.setBackgroundDrawable(new ColorDrawable(context.getResources().getColor(android.R.color.transparent)));
    mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
    WindowAdapter adapter = new WindowAdapter();
    mRecyclerView.setAdapter(adapter);

}

class WindowAdapter extends RecyclerView.Adapter<WindowViewHolder>{

    @Override
    public WindowViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.item, null);
        final WindowViewHolder holder = new WindowViewHolder(view);
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onItemClickListener != null) {
                     int layoutPosition = holder.getLayoutPosition();
                     String data = mList.get(layoutPosition);
                     onItemClickListener.click(v,data);
                }
            }
        });
        return holder;
    }

    @Override
    public void onBindViewHolder(WindowViewHolder holder, int position) {
        holder.setText(R.id.tvName,mList.get(position));
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }
}

class WindowViewHolder extends RecyclerView.ViewHolder{
    private SparseArray<View> views = new SparseArray<>();
    private View mRootView;
    public WindowViewHolder(View itemView) {
        super(itemView);
        mRootView = itemView;
    }

    public <T extends View>T getView(int id){
        View view = views.get(id);
        if (view == null) {
            view = mRootView.findViewById(id);
            views.put(id,view);
        }
        return (T)view;
    }

    public void setText(int id,String str){
        ((TextView) getView(id)).setText(str);
    }
}

public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
    this.onItemClickListener = onItemClickListener;
}

public interface OnItemClickListener{
    void click(View view,String item);
}

public void show(View v,int gravity,int x,int y){
    popupWindow.showAtLocation(v,gravity,x,y);
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值