A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

默认的popupWindow点击区域外会使popupWindow自动dismiss,如果有一个点击区域外使popupWindow不自动dismiss的需求,该怎么办呢?

首先来看popupWindow的两个重要的boolean属性mFocusable和mOutsideTouchable。
    mFocusable是用来判断当前的popupWindow是否获取焦点,可以通过setFocusable(boolean focusable)来设置。
    mOutsideTouchable是用来判断点击当前的popupWindow区域外的touch事件是否有效,可以通过setOutsideTouchable(boolean touchable)来设置,默认值是false。

如果设置popupWindow的setFocusable( true ),那么设置setOutsideTouchable ( false )是没有作用的,点击区域外依然会dismiss。来看看mOutsideTouchable属性的官方声明:



  • /**



  • * <p>Controls whether the pop-up will be informed of touch events outside



  • * of its window. This only makes sense for pop-ups that are touchable



  • * but not focusable, which means touches outside of the window will



  • * be delivered to the window behind. The default is false.</p>



  • *



  • * <p>If the popup is showing, calling this method will take effect only



  • * the next time the popup is shown or through a manual call to one of



  • * the {@link #update()} methods.</p>



  • *



  • * @param touchable true if the popup should receive outside



  • * touch events, false otherwise



  • *



  • * @see #isOutsideTouchable()



  • * @see #isShowing()



  • * @see #update()



  • */



  • public void setOutsideTouchable(boolean touchable) {



  • mOutsideTouchable = touchable;



  • }


翻译下:



  • 控制popupWindow区域外的点击事件是否有效。这个只有在popupWindow能点击但是没有获取焦点的情况下才有作用,作用是区域外的点击事件会传递到window后面的activity。



  • 如果popupwindow已经在显示了,只能使popupwindow下一次show或者调用update( )使mOutsideTouchable生效。



  • 当mOutsideTouchable为true时,popupwindow可以接收到区域外的点击事件,反之则不行。


当设置popupWindow的setFocusable( false ),那么设置setOutsideTouchable ( true ) 时,点击区域外会dismiss,setOutsideTouchable 终于起作用了。也就是mOutsideTouchable只有在mFocusable为false的时候才有作用。

当设置popupWindow的setFocusable( false ),设置setOutsideTouchable ( false ) 时会有什么效果呢?答案是popupWindow是不会dismiss的,但是区域外的点击事件已经传递到popupwindow下面的activity了,点击activity下面的控件会有作用的。这就坑爹了,点击区域外不消失的效果是做到了,可是点击区域外,也就是popupWindow下面的activity的控件例如button时会响应onClickListener的。那该怎么使activity不分发popupWindow区域外的点击事件呢?

activity中有两个重要的处理事件的方法dispatchTouchEvent和onTouchEvent。在这里主要是利用了
dispatchTouchEvent。

dispatchTouchEvent负责事件的分发,调用super.dispatchTouchEvent才会往下如ViewGroup传递事件。Activity中当dispatchTouchEvent返回false或者true时:事件停止传递,没继续往下传递,事件被消费了。

那我们就重写activity中dispatchTouchEvent,在里面判断popupWindow是否显示来决定是否往下分发事件。



  • @Override



  • public boolean dispatchTouchEvent(MotionEvent event){



  • if(mPopupWindow!=null&&mPopupWindow.isShowing()){



  • return false;



  • }



  • return super.dispatchTouchEvent(event);



  • }


  • popupWindow的设置:


    • mPopupWindow=new PopupWindow(selectView, ViewGroup.LayoutParams.MATCH_PARENT,



    • ViewGroup.LayoutParams.WRAP_CONTENT,true);



    • mPopupWindow.setFocusable(false);



    • mPopupWindow.setOutsideTouchable(false);



    • mPopupWindow.showAtLocation(findViewById(R.id.EditActivity_rootView), Gravity.BOTTOM,0,0);



  • OK,大功告成。现在点击popupWindow区域外终于不会使popupWindow dismiss了,也不会使下面的activity控件得到响应了,perfect 完美!

这个可以解决android 6.0 以上点击popupWindow区域外不消失的解决方法。


4 个回复

正序浏览
回复 使用道具 举报
回复 使用道具 举报
奈斯
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马