本博客是查看以下俩篇完成的:
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);
}
}