在做輔助器的時候 要搞一個全域彈窗,用的 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();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/165248.html
標籤:python
上一篇:AS開發工程軟體
