当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 进行分发。

@Override
    public 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;
    }

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值