Android WindowManager 全局悬浮窗 + AccessibilityService+ RecyclerView 拖动和点击
16lz
2021-01-23
在做辅助器的时候 要搞一个全局弹窗,用的 RecyclerView 加载了一些按钮,其中遇到一个小问题 ,就是拖动 RecyclerView 时发现手指坐标不对,研究了一下 发现是初始化的问题。
具体看代码中的注释即可。
重点在于
myFloatViewParama.setX( (int) event.getRawX() ); myFloatViewParama.setY((int) event.getRawY());
/**viewGroup 拦截手势 实现 可以拖动viewgroup 时不影响 其中的view的点击事件。 */public class MyRecyclerView extends RecyclerView{ private int minTouchSlop=0; private float mDownX; private float mDownY; public MyRecyclerView(@NonNull Context context) { this(context ,null); } public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) { this(context ,attrs ,0); } public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initView(context); } private void initView(Context context){ minTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } /** * todo onInterceptTouchEvent 用来决定是否拦截事件。 * 判断出为拖动手势就把事件拦截下来,实现viewGroup的拖动效果。 * 如果是点击效果 就不拦截事件,让子 view 响应点击事件。 */ @Override public boolean onInterceptTouchEvent(MotionEvent event) { boolean interceptd =false ; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: interceptd = false; mDownX = event.getX(); mDownY = event.getY(); // todo 重要点,要在此处初始化位置参数,否则拖动时效果有偏差。 // 因为 onTouchEvent 的 MotionEvent.ACTION_DOWN 不一定会被触发。 myFloatViewParama.setX( (int) event.getRawX() ); myFloatViewParama.setY((int) event.getRawY()); break; case MotionEvent.ACTION_MOVE: float dx = event.getX() - mDownX; float dy = event.getY() - mDownY; // 根据滑动的距离来判断是否是拖动操作 interceptd = Math.abs(dx) > minTouchSlop || Math.abs(dy) > minTouchSlop ; break; case MotionEvent.ACTION_UP: interceptd = false; break; } return interceptd; } private MyFloatViewParama myFloatViewParama ; private WindowManager windowManager ; public void updateConfig(MyFloatViewParama myFloatViewParama, WindowManager windowManager){ this.myFloatViewParama =myFloatViewParama ; this.windowManager=windowManager; } @Override public boolean onTouchEvent(MotionEvent event) { if(myFloatViewParama==null){ return false ; } if(windowManager ==null){ return false; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //todo 因为 ViewGroup 中有 子View 被挡触摸时, ViewGroup ACTION_DOWN 没法被 // 触发,所以为了确保触发,要在 onInterceptTouchEvent ACTION_DOWN 中进行初始化。 myFloatViewParama.setX( (int) event.getRawX() ); myFloatViewParama.setY((int) event.getRawY()); break; case MotionEvent.ACTION_MOVE: int nowX = (int) event.getRawX(); int nowY = (int) event.getRawY(); int movedX = nowX - myFloatViewParama.getX(); int movedY = nowY - myFloatViewParama.getY(); myFloatViewParama.setX( nowX ); myFloatViewParama.setY( nowY ); myFloatViewParama.getLayoutParams().x = myFloatViewParama.getLayoutParams().x + movedX; myFloatViewParama.getLayoutParams().y = myFloatViewParama.getLayoutParams().y + movedY; windowManager.updateViewLayout(this, myFloatViewParama.getLayoutParams()); break; case MotionEvent.ACTION_UP: performClick(); break; default: break; } return super.onTouchEvent(event); } @Override public boolean performClick() { return super.performClick(); }}
更多相关文章
- Android23-视图坐标系以及MotionEvent事件
- [Android]ButterKnife-无尽之刃-绑定视图控件和事件的快速开发工
- android 监听事件的处理
- Android实现View的任意拖动
- android广播事件机制及应用(实现简单的定时提醒功能) 转
- Android基于多触控的图片缩放和拖动代码实现
- android常驻通知栏点击事件