Представление перетаскивания переполнения имеет странную ошибку на android - PullRequest
0 голосов
/ 05 мая 2020

Я пытаюсь перетащить представление переполнения по экрану на 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

...