本文主要是介绍当Fragment遇见PopWindow,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
问题描述:
页签1控制Fragment1,页签2控制Fragmeng2。
Fragment1和Fragment2 上各有一个按钮,要求点击按钮弹出弹出框。
我们要求点击外部弹出框消失。
问题来了:当Fragment1 弹出popWindow 时,点击页签2,popwindow 消失了,但是fragment2没有切换。
原因:我们设置了setOutsideTouchable(true)。
什么意思呢,如何设置了了true,那么弹窗外的触摸事件将会分配给window。就是说导航签的触摸事件被window消费了,所以页签拿不到点击事件。
解决思路:
setOutsideTouchable(false)。那么并发症来了,当popwindow 处于showing状态时,点击页签外部都不生效。
事件是怎么传递的,我们能否自定义事件?
首先明白事件是怎么传递的:
事件由Activity--->Window-->DecorView-->ViewGroup-->View 一层一层分发下去。
ViewGrop 和View 的相同点是:都有dispathTouchEvent 和onTouchevent 方法。不同点是View 没有 onInterceptTouchEvent 方法。
灵感来了,我们可以在Activity的dispatchTouchEvent 中动手脚。
首先:popwindow的事件不会经过Activity 进行分发。
@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {int x = (int) ev.getRawX();//点击的x坐标int y = (int) ev.getRawY();//点击的y坐标if (fragment1!= null) {if (fragment1.mPopWindow != null && fragment1.mPopWindow.isShowing()) {fragment1.mPopWindow.dismiss();//是否点击当行页签if (clickInBottomButton(x, y)) {//事件交由actiivty分发处理,最终会默认达到页签return super.dispatchTouchEvent(ev);} else {//事件不进行分发,如:我们不希望点击fragment1中列表中item,进行页面跳转return false;}}}if (fragment2!= null) {if (fragment2.mPopWindow != null && fragment2.mPopWindow.isShowing()) {fragment2.mPopWindow.dismiss();if (clickInBottomButton(x, y)) {return super.dispatchTouchEvent(ev);} else {return false;}}}return super.dispatchTouchEvent(ev);}
点击排除区域:
RadioButton radioButton1 = findViewById(R.id.radio_button1);
private Rect fragment1ButtonReact= new Rect();
radioButton1.getGlobalVisibleRect(fragment1ButtonReact);//获取底部按钮区域
/****排除点击区域* @param x* @param y* @return*/public boolean clickInBottomButton(int x, int y) {if (clickInRect(x, y, fragment1ButtonReact)) {return true;}if (clickInRect(x, y, fragment2ButtonReact)) {return true;}return false;}
这篇关于当Fragment遇见PopWindow的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!