python accessibilityservice_Android WindowManager 全局悬浮窗 + AccessibilityService+ RecyclerView 拖动和点击...

本文介绍了如何在Android中实现全局悬浮窗,使用RecyclerView展示内容,并结合AccessibilityService实现拖动和点击功能。关键在于在onInterceptTouchEvent中判断拖动和点击事件,初始化悬浮窗位置参数,并在ACTION_MOVE中更新位置。
摘要由CSDN通过智能技术生成

在做辅助器的时候 要搞一个全局弹窗,用的 RecyclerView 加载了一些按钮,其中遇到一个小问题 ,就是拖动 RecyclerView 时发现手指坐标不对,研究了一下 发现是初始化的问题。

具体看代码中的注释即可。

a22491d5d79d1df4d7a1b7f399b2685e.gif

重点在于

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();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值