如何实现滑动填充全屏绿框 无需逐个点击网格方格
问题需求
想要通过平滑的非线性滑动操作激活屏幕上的所有点位,无需逐个点击单个方格。当前功能仅支持逐格点击生效,沿环形等路径滑动时无法选中空白方格。
当前实现代码
@Override public void onItemTouched(View view, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (view.getTextAlignment() == View.TEXT_ALIGNMENT_CENTER) { view.setBackgroundColor(getResources().getColor(R.color.correct)); view.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START); contTouchCounter += 2; Log.i(TAG, "onItemTouched: " + contTouchCounter); } if (contTouchCounter == 100) { disposable.dispose(); linearContTouch.setVisibility(View.GONE); cont_touch.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_baseline_check_circle_outline_24)); cont_touchTxt.setVisibility(View.GONE); multimediaInfo.setContTouch(String.valueOf(contTouchCounter)); isContTouchStarted = false; goToNextActivity(); } } }
已尝试操作
将代码中的ACTION_DOWN改为ACTION_MOVE,但功能没有正常生效。
界面截图

解决方案
问题原因
你当前的触摸回调是绑定在单个方格View上的,Android默认触摸事件只会派发给最初触发ACTION_DOWN的View,滑动过程中触摸点移动到其他方格时,事件不会传递给路径上的其他方格,因此不会触发对应方格的回调逻辑。
修复步骤
- 将触摸监听从单个方格迁移到所有方格的父布局容器,接管整个方格区域的触摸事件
- 每次收到
ACTION_DOWN/ACTION_MOVE事件时,计算当前触摸坐标命中的方格 - 对命中的未激活方格执行激活逻辑,新增去重判断避免同一方格被重复计数
示例实现代码
// 全局声明已激活方格存储集合,避免重复计数 private HashSet<View> activatedViews = new HashSet<>(); // 给方格父布局设置触摸监听,替换原单个方格的触摸监听 gridParentLayout.setOnTouchListener((v, event) -> { int action = event.getActionMasked(); // 按下时清空已激活集合,重置本次滑动的计数状态 if (action == MotionEvent.ACTION_DOWN) { activatedViews.clear(); } // 处理按下和滑动两类事件 if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) { float touchX = event.getX(); float touchY = event.getY(); // 遍历父布局下的所有方格子View for (int i = 0; i < gridParentLayout.getChildCount(); i++) { View gridItem = gridParentLayout.getChildAt(i); // 判断触摸点是否在当前子View的范围内 if (touchX >= gridItem.getLeft() && touchX <= gridItem.getRight() && touchY >= gridItem.getTop() && touchY <= gridItem.getBottom()) { // 仅处理未激活过的符合条件的方格 if (!activatedViews.contains(gridItem) && gridItem.getTextAlignment() == View.TEXT_ALIGNMENT_CENTER) { // 原有激活逻辑 gridItem.setBackgroundColor(getResources().getColor(R.color.correct)); gridItem.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START); contTouchCounter += 2; Log.i(TAG, "onItemTouched: " + contTouchCounter); activatedViews.add(gridItem); // 原有完成逻辑 if (contTouchCounter == 100) { disposable.dispose(); linearContTouch.setVisibility(View.GONE); cont_touch.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_baseline_check_circle_outline_24)); cont_touchTxt.setVisibility(View.GONE); multimediaInfo.setContTouch(String.valueOf(contTouchCounter)); isContTouchStarted = false; goToNextActivity(); } } break; } } return true; } return false; });
额外优化建议
- 如果方格是用RecyclerView/GridView实现的,可以调用控件的
pointToPosition(touchX, touchY)方法直接获取命中的方格位置,无需遍历所有子View,性能更优 - 如需支持多指滑动,可以补充处理
ACTION_POINTER_DOWN、ACTION_POINTER_MOVE事件,适配多触点场景
内容的提问来源于stack exchange,提问作者Ahmed Hassan
相关产品推荐
相关产品推荐

