Search code examples
androidontouchlistenerandroid-windowmanager

Android : WindowManager.UpdateViewLayout() not working


I am showing camera preview on top using system alert. And I am trying to make it draggable. Initially I am drawing it on top left conrner. But on dragging it, it just comes to the center of the screen and doesn't move after that. Here is how I am adding relative layout :

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

Here is the code for 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;
}

As you can see in Action Move I have already tried removing the view and the adding it again with new layout parameters but it does the same thing. I can drag a button in an activity with this same code but not this. What am I doing wrong?


Solution

  • Finally I found what was causing it. The problem was with the 'if' condition where I was trying to determine if user has touched inside the view or outside. It wasn't updating the location of relative layout after dragging.

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

    I commented the if condition and its working as expected. But I am not sure what was problem with 'getLeft()' and 'getTop()'. I also tried 'getLocationInWindow()' but it didn't update the relative layout's location in screen too. If anyone finds the problem please share. And thanks for your help.