Android : WindowManager.UpdateViewLayout() 不工作

Android : WindowManager.UpdateViewLayout() not working

我正在使用系统警报在顶部显示相机预览。我正试图让它可以拖动。最初我把它画在左上角。但是在拖动它时,它只是到达屏幕的中心并且之后不会移动。 这是我添加相对布局的方式:

RelativeLayout.LayoutParams sf_lp = new RelativeLayout.LayoutParams(xlen,ylen);
    relativeLayout.addView(surfaceView,sf_lp);
    WindowManager.LayoutParams wLayoutParams = new WindowManager.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT,0,0,WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT);
    wLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
    windowManager.addView(relativeLayout,wLayoutParams);

这是 OnTouch 的代码:

public boolean onTouch(View v, MotionEvent event) {
    int X = (int) event.getRawX();
    int Y = (int) event.getRawY();
    int xpos = relativeLayout.getLeft();
    int ypos = relativeLayout.getTop();

    if(X >= xpos && X <= xpos+relativeLayout.getWidth() && Y >= ypos && Y <= ypos+relativeLayout.getHeight())
    {
        Toast.makeText(this,"X="+X+", "+"Y="+Y+"-Touched inside",Toast.LENGTH_SHORT).show();
        switch(event.getAction() & MotionEvent.ACTION_MASK)
        {
            case MotionEvent.ACTION_DOWN :
                WindowManager.LayoutParams wlp = (WindowManager.LayoutParams) v.getLayoutParams();
                dx = X - wlp.x;
                dy = Y - wlp.y;
                Log.v("onTouch", "Action Down:X=" + X + ", Y=" + Y + " ,dx=" + dx + " ,dy=" + dy);
                break;
            case MotionEvent.ACTION_UP : Log.v("onTouch","Action Up:X="+X+", Y="+Y+" ,dx="+dx+" ,dy="+dy);
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                break;
            case MotionEvent.ACTION_POINTER_UP:
                break;
            case MotionEvent.ACTION_MOVE :
                //windowManager.removeView(v);
                Log.v("ACTION_MOVE","X="+ (X-dx) +"Y="+ (Y-dy));
                //((TextView) v.findViewWithTag("tv")).setText("X="+ (X-dx) +"Y="+ (Y-dy));
                WindowManager.LayoutParams wlp1 = new WindowManager.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT);
                wlp1.x = X-dx;
                wlp1.y = Y-dy;
                windowManager.updateViewLayout(v,wlp1);
                //windowManager.addView(v,wlp1);
                //v.animate().x(X-dx).y(Y-dy).setDuration(0).start();
                Log.v("onTouch", "Action Move:X=" + X + ", Y=" + Y + " ,dx=" + dx + " ,dy=" + dy);
                break;
        }
    }
    else
    {
        Toast.makeText(this,"X="+X+", "+"Y="+Y+"-Touched Outside",Toast.LENGTH_SHORT).show();
    }
    return false;
}

正如您在 Action Move 中看到的那样,我已经尝试删除视图并使用新的布局参数再次添加它,但它做同样的事情。我可以使用相同的代码在 activity 中拖动一个按钮,但不是这个。我做错了什么?

I had tried the same using below code and using surfaceview directly rather than relative layout

preview.setOnTouchListener(new View.OnTouchListener() {
                    private int initialX;
                    private int initialY;
                    private float initialTouchX;
                    private float initialTouchY;

                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        switch (event.getAction()) {
                            case MotionEvent.ACTION_DOWN:
                                initialX = params.x;
                                initialY = params.y;
                                initialTouchX = event.getRawX();
                                initialTouchY = event.getRawY();
                                return true;
                            case MotionEvent.ACTION_UP:
                                return true;
                            case MotionEvent.ACTION_MOVE:
                                params.x = initialX + (int) (event.getRawX() - initialTouchX);
                                params.y = initialY + (int) (event.getRawY() - initialTouchY);


                                windowManager.updateViewLayout(preview, params);
                                return true;
                        }
                        return false;
                    }
                });

我终于找到了导致它的原因。问题出在 'if' 条件下,我试图确定用户是在视图内部还是外部进行了触摸。拖动后没有更新相对布局的位置。

   int xpos = relativeLayout.getLeft();
    int ypos = relativeLayout.getTop();
    if(X >= xpos && X <= xpos+relativeLayout.getWidth() && Y >= ypos && Y <= ypos+relativeLayout.getHeight())
{

}

我评论了 if 条件及其按预期工作。但我不确定 'getLeft()' 和 'getTop()' 有什么问题。我也试过 'getLocationInWindow()' 但它也没有更新屏幕中的相对布局位置。如果有人发现问题,请分享。感谢您的帮助。