Я пытаюсь перетащить представление переполнения по экрану на android.
это представление должно быть перекрыто другими действиями
, но у меня возникают две ОЧЕНЬ ОЧЕНЬ неприятные проблемы:
1 - при отбрасывании, тень вида показывает быструю анимацию, показывающую координаты to-> from ... как это остановить?
2- конечная позиция представления мягко ниже, чем позиция пользователя бросает его ... кажется, есть невидимое поле, которое я не установил, и я не могу удалить.
public class OverlayLayout extends ViewGroup {
private final SharedPreferences sp;
private final WindowManager wm;
private float originalOffsetY;
private float originalOffsetX;
@SuppressLint("ClickableViewAccessibility")
public OverlayLayout(Context context) {
super(context);
this.sp = PreferenceManager.getDefaultSharedPreferences(getContext());
this.wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
setContentView();
this.setOnDragListener((v, event) -> {
if (event.getAction() == DragEvent.ACTION_DRAG_ENDED) {
int x = (int) (event.getX() - originalOffsetX);
int y = (int) (event.getY() - originalOffsetY);
int type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O)
type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
300,
300,
this.sp.getInt(Constants.SharedPref.AIM_X, 0),
this.sp.getInt(Constants.SharedPref.AIM_Y, 0),
type,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.START | Gravity.TOP;
params.horizontalMargin = 0;
params.verticalMargin = 0;
params.x = x;
params.y = y;
this.wm.updateViewLayout(v, params);
this.sp.edit().putInt(Constants.SharedPref.AIM_X, x).putInt(Constants.SharedPref.AIM_Y, y).apply();
this.setVisibility(View.VISIBLE);
}
return true;
});
this.setOnTouchListener((view, event) -> {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view) {
public void onProvideShadowMetrics(Point shadowSize, Point touchPoint) {
shadowSize.set(view.getWidth(), view.getHeight());
touchPoint.set((int) event.getAxisValue(MotionEvent.AXIS_X), (int) event.getAxisValue(MotionEvent.AXIS_Y));
}
};
view.startDrag(data, shadowBuilder, view, 0);
view.setVisibility(View.INVISIBLE);
this.originalOffsetX = event.getAxisValue(MotionEvent.AXIS_X) - view.getX();
this.originalOffsetY = event.getAxisValue(MotionEvent.AXIS_Y) - view.getY();
return true;
} else {
return false;
}
});
}
private void setContentView() {
this.setBackgroundColor(Color.CYAN);
int type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O)
type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
300,
300,
this.sp.getInt(Constants.SharedPref.AIM_X, 0),
this.sp.getInt(Constants.SharedPref.AIM_Y, 0),
type,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.START | Gravity.TOP;
params.horizontalMargin = 0;
params.verticalMargin = 0;
this.wm.addView(this, params);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
}
, чтобы запустить его, просто вызовите из любого действия:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, Constants.RequestCode.OVERLAY_PERMISSION);
} else
createOnTopView();
Я сделал короткое видео, чтобы показать проблему ... к сожалению, указатель мыши не отображается ... но поверьте мне, я даже немного не сдвинул его во время первого шага видео
https://youtu.be/0lyF1_Exgd4