关闭

Popwindow未解决popwindow外点击消失

994人阅读 评论(0) 收藏 举报
分类:
这个功能应该是不难的,查了下文档,没发现明显的方法可以调用。

开始以为popupWindow.setOutsideTouchable(true);这个方法可以呢,试了试,不行,其实这个方法时设置popupWindow以外的区域可以相应触摸事件,比如我们重写了触摸事件去做一些别的操作。

对了,还有,设置popupWindow.setFocusable(true); 这样才能让popupWindow里面的布局控件获得点击的事件,否则就被它的父亲view给拦截了。

如果你想处理back事件,就要重写popupWindow布局文件的onKeyListener()事件,这样才能自己做处理。比如下面的几行代码:
.setOnKeyListener(new OnKeyListener()
{// 手机键盘上的返回键
public boolean onKey(View v, int keyCode, KeyEvent event)
{
switch (keyCode)
{
case KeyEvent.KEYCODE_BACK:
if (softkeyboard_popupWindow != null && softkeyboard_popupWindow.isShowing())
{
softkeyboard_popupWindow.dismiss();
}
break;
}
}



一个朋友这样想的办法:(问题是setFocusable(false),这样后,里面的布局控件不能获得焦点,如果有一个EditText,就不能输入内容了,肯定是不行的。我想了想,可以设置setOutsideTouchable(true);,让popupWindow以外的布局可以获得触摸事件,然后我们重写onTouchEvent,去让popupWindow消失,如下面写的一样。
又测试了一下,终于明白了,.setFocusable(false),之所以要设置为false,就是为了让popupWindow出现的时候,它所依赖的父亲view仍然能获取到焦点,这样重写onTouchEvent就可以起作用了,如果设置为true,当你的popupWindow出现的时候,它的父亲view是获取不到焦点的,所以你重写onTouchEvent也没用,根本截获不到这个事件。
代码如下popupWindow.setFocusable(false);//focusable要为false(不设置默认的就是False);
//这是Activity 的OnTouchEvent。OnTouchEvent代表的是Activity 获得事件(即为PopupWindow之外)

@Override

public boolean onTouchEvent(MotionEvent event) {

// TODO Auto-generated method stub

if (popupWindow != null && popupWindow.isShowing()) {

popupWindow.dismiss();

popupWindow = null;

}

return super.onTouchEvent(event);

}




还有一个朋友记录了一些他的学习内容。如下:

由于系统自带的Menu不好看 而且不能自己改样式
所以很多应用都用Popupwindow自定义了
最精典的莫过于UC和天天的Menu鸟

网上有模仿UCweb的自定义menu的源码,下面是三个比较经典的文章:
这三个都是使用PopupWindow来做的,然后往PopupWindow增加一个子View,子View的布局就是menu的布局。
出现和退出的动画:可以给PopUpWindow或它的子view。这些问题可以看看上面三个例子的源码。

网上所有用PopupWindow做的menu有个共同特点:就是点击menu键出现PopupWindow,然后再点击menu键无法使 PopupWindow退出/dismiss()。甚至有的会多此一举,点击一个按钮显示menu,同时还在按钮点击事件写了这时候点击按钮,menu会 退出的代码。
为什么说多此一举呢?因为当给PopupWindow设置了setFocusable(true),menu显示后,点击menu其他任何地 方,menu都会消失,也就是说这时候按钮的点击事件其实是不响应的。同时只响应键盘的返回键,其他按键均不响应,比如点击menu键,没有任何反应。
要解决这个问题很简单,就是给PopupWindow的子View设置下面的代码:
menuView.findViewById(R.id.layout).setOnKeyListener(
new OnKeyListener() {

public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
Log.w("qqqqqq", "onKey");
if (keyCode == KeyEvent.KEYCODE_MENU) {

showPopup();
}
return false;
}
});



记住,一定要给PopupWindow设置setFocusable(true),要不然点击menu其他地方以及返回键,menu都不会退出。且这时候是响应PopupWindow的parent的menu事件的。
下面阐述为什么这么写之后,当PopupWindow显示后,点击menu键PopupWindow会退出的原因:
首先得明白为什么给PopupWindow setFocusable(true)后,点击menu出现PopupWindow后再点击menu没反应的原因。PopupWindow初始化的时候一 般都指定了在哪个View上出现,我们称这个View为parent。parent里面写了点击menu出现PopupWindow的事件,如果给 PopupWindow setFocusable(true),此时屏幕的焦点在PopupWindow上面,肯定是不会响应parent的按键事件的,它只会响应 PopupWindow的按键事件。
但是PopupWindow的本质是Window,没有继承View类,自己没有onkeyDown或onkey或dispatchKey这些事件的。我刚开始试着实现这些接口,但是按键依然不响应,不知原因。因现在对按键的原理还不熟,无法阐述其原因。

然后我想绕道而行,就是给PopupWindow的子View注册按键事件,setKeyListener,刚开始我在子View的xml设置了 android:focusable=”true” 但按键事件依然不响应。。。。纠结啊纠结。。。然后没得办法,我google了所有关于PopupWindow的文章。。。最后终于被我发现。。。需要给 PopupWindow的子View 设置setFocusableInTouchMode(true)。这时候按键事件就响应了。。。
最后加红的这段代码可困扰我好几天啊,就一个属性 我是翻来覆去整了好几天啊
赶紧记录一下


最终的办法:
其实这里还是有办法的,一行代码就可以,网上很多朋友说这个是PopupWindow的一个bug.
popupWindow.setBackgroundDrawable(null);//new BitmapDrawable());
文档上写可以设置一个背景图或者设为null,但是设置为null是不行的,感兴趣的朋友可以试试。
popupWindow.setBackgroundDrawable(new BitmapDrawable());这样设置一下就可以实现标题说的了,点击popupWindow以外的区域就可以让它消失了。其实我看了BitmapDrawable这个类,这个类的无参构造函数已经标为@deprecated了,就是说已经不建议使用了。我们这里这么用也是投机取巧了。
如果你想让它消失的时候做一些事情,就可以重写setOnDismissListener(PopupWindow.OnDismissListener onDismissListener)这个方法,去写个回调函数,去做你想做的操作。

还有一个发现:我们设置popupWindow的布局文件如下:这样可以相应back事件,这样就是说在popupWindow获取焦点的时候,拦截
它的back事件,然后让popupWindow消失。其实,这个时候,popupWindow里面布局的任何一个控件,比如Button,都可以拦截onKeyListener事件了。
当然你可以设置popupWindow里面布局每个子控件的属性,然后在事件里做一些你想做的操作,比如:
button.setFocusableInTouchMode(true);
button.setOnKeyListener(new View.OnKeyListener() { });

contentView.setFocusableInTouchMode(true);
contentView.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
Log.i("tag", "XXX0");
if (keyCode == KeyEvent.KEYCODE_BACK) {
popupWindow.dismiss();
}
return false;

}
});

又发现朋友给了这个方法:
你把除popwindow意外的区域 用一个linear圈起来。。。然后这个linear设置ontouch监听。。event.getAction()==MotionEvent.ACTION_UP 时 ,popwindow.dismiss();

看了以上的方法,自己亲自试了下,扔未解决返回键触发和窗口外触发popwindow.dismiss,郁闷了!
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:254537次
    • 积分:4775
    • 等级:
    • 排名:第6271名
    • 原创:225篇
    • 转载:36篇
    • 译文:0篇
    • 评论:33条
    最新评论