Petterpx/FloatingX

悬浮窗布局中如果设置了布局中View的点击事件,当点击某个View后拖动悬浮窗会出现跳动

Closed this issue · 4 comments

复现步骤:
1、为悬浮窗布局中的某个view设置点击事件:
可以把布局宽高设置大一点,方面点击看效果

addItemView("显示全局悬浮窗") {
    FloatingX.control(MultipleFxActivity.TAG_1).apply {
        updateViewContent { holder ->
            val tv = holder.getViewOrNull<TextView>(R.id.tvItemFx)
            tv?.setOnClickListener {
                Toast.makeText(this@MainActivity, "文字被点击", Toast.LENGTH_SHORT).show()
            }
        }
    }.show(this@MainActivity)
}

2、启动应用,点击隐藏全局悬浮窗,然后点击展示全局悬浮窗,让悬浮窗重新出现一次。(如果一开始就设置enableFx让悬浮窗展示出来,就不会有问题,原因是设置了enableFx以后,不知道为什么点击文字的时候会触发FxManagerView的onTouchEvent,导致状态反而没问题,具体为啥会回调onTouchEvent没细查)
3、正常拖动悬浮窗,行为正常;先点击文字,然后再次拖动悬浮窗,悬浮窗会跳动

原因:
FxManagerView在onInterceptTouchEvent中的down事件记录了点击,但是没有处理up事件。导致位置错乱

修复:
在FxManagerView的onInterceptTouchEvent中处理up、cancel等事件

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        var intercepted = false
        when (ev.actionMasked) {
            MotionEvent.ACTION_DOWN -> {
                initTouchDown(ev)
                helper.fxLog?.d("fxView---onInterceptTouchEvent-[down]")
            }

            MotionEvent.ACTION_MOVE -> {
                intercepted = configHelper.checkInterceptedEvent(ev)
                helper.fxLog?.d("fxView---onInterceptTouchEvent-[move], interceptedTouch-$intercepted")
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                touchToPointerUp(ev, performClick = false)
            }
        }
        return intercepted
    }

    private fun touchToPointerUp(event: MotionEvent, performClick: Boolean = true) {
        if (configHelper.isCurrentPointerId(event)) {
            touchToCancel(performClick)
        } else {
            helper.fxLog?.d("fxView---onTouchEvent--ACTION_POINTER_UP---id:${event.pointerId}->")
        }
    }

    private fun touchToCancel(performClick: Boolean = true) {
        moveToEdge()
        helper.iFxScrollListener?.up()
        configHelper.touchDownId = INVALID_TOUCH_ID
        if (performClick) {
            clickHelper.performClick(this)
        }
        helper.fxLog?.d("fxView---onTouchEvent---MainTouchCancel->")
    }

启动应用,点击隐藏全局悬浮窗,然后点击展示全局悬浮窗,让悬浮窗重新出现一次。(如果一开始就设置enableFx让悬浮窗展示出来,就不会有问题,原因是设置了enableFx以后,不知道为什么点击文字的时候会触发FxManagerView的onTouchEvent,导致状态反而没问题,具体为啥会回调onTouchEvent没细查)

有空再细查吧,最近在重构浮窗中,后续会处理下这里的问题。

如果你有空,可以先改一下,提个fix,开源需要一起维护呢 :)

启动应用,点击隐藏全局悬浮窗,然后点击展示全局悬浮窗,让悬浮窗重新出现一次。(如果一开始就设置enableFx让悬浮窗展示出来,就不会有问题,原因是设置了enableFx以后,不知道为什么点击文字的时候会触发FxManagerView的onTouchEvent,导致状态反而没问题,具体为啥会回调onTouchEvent没细查)

有空再细查吧,最近在重构浮窗中,后续会处理下这里的问题。

问题找到了,如果设置enableFx,那么悬浮窗会直接展示出来,但是我的点击事件是在MainActivity的按钮点击事件中设置的,所以需要点击按钮才能真正设置上view的点击事件。这个对于问题解决没有影响。
我已经提交了一个PR了。PR

启动应用,点击隐藏全局悬浮窗,然后点击展示全局悬浮窗,让悬浮窗重新出现一次。(如果一开始就设置enableFx让悬浮窗展示出来,就不会有问题,原因是设置了enableFx以后,不知道为什么点击文字的时候会触发FxManagerView的onTouchEvent,导致状态反而没问题,具体为啥会回调onTouchEvent没细查)

有空再细查吧,最近在重构浮窗中,后续会处理下这里的问题。

问题找到了,如果设置enableFx,那么悬浮窗会直接展示出来,但是我的点击事件是在MainActivity的按钮点击事件中设置的,所以需要点击按钮才能真正设置上view的点击事件。这个对于问题解决没有影响。 我已经提交了一个PR了。PR

感谢修复,更新到 1.4.1 即可