Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WindowManager not allowing to pass touch

I have drawn an overlay using WindowManager. it's width and height are WindowManager.LayoutParams.MATCH_PARENT with transparent background.

My view must be match parent and handle circle touch listener and pass the rest touch to the below screen

I have two small circle in left and right corner. I make them draggable on screen that's working fine. But when I click on visible Home Screen button. WindowManager don't let the visible item clickable.

        int LAYOUT_FLAG = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.
                LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_PHONE;

        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT,//changed it to full
                WindowManager.LayoutParams.MATCH_PARENT,
                LAYOUT_FLAG,

                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                |WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                ///| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, this flag can make it in touchable.
                ///WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                PixelFormat.TRANSLUCENT);

        mFloatingView = LayoutInflater.from(this).inflate(R.layout.item_circle_dragging, null);

        mFloatingView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                return false;
            }
        });
        //Add the view to the window
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mWindowManager.addView(mFloatingView,params);

item_circle_dragging.xml

<?xml version="1.0" encoding="utf-8"?>
<customviewpracticing.CircleDraggingView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</customviewpracticing.CircleDraggingView>

CircleDragginView onTouchEvent

@Override
public boolean onTouchEvent(MotionEvent event) {

   switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
          if(isPointInside(event.getRawX(),event.getRawY()))
            isAllowedToDrag = true;
          Log.d(TAG, "ACTION_DOWN:getRawX= " + event.getRawX() + " getRawY= " + event.getRawY() + " getX= "
                + event.getX() + " getY= " + event.getY());
          break;
        ///return true;
      case MotionEvent.ACTION_MOVE:
          Log.d(TAG, "ACTION_MOVE:getRawX= " + event.getRawX() + " getRawY= " + event.getRawY() + " getX= "
                + event.getX() + " getY= " + event.getY());
          if(isAllowedToDrag){
            center_circle_X = event.getRawX() ;
            center_circle_Y = event.getRawY();
            }/*this.animate().x(event.getRawX()).y(event.getRawY())
                    .setDuration(50).start();*/
          break;
      case MotionEvent.ACTION_UP:
         if(isAllowedToDrag)
            isAllowedToDrag = false;
         break;
      default:
        return true;//I changed it
   }
    // Force a view to draw again
    ///postInvalidate();
    invalidate();
    return true;
}

Also tried returning false in onTouchEvent of CircleDraggingView and also to main mFloatingView (Root View ).

like image 326
Zar E Ahmer Avatar asked Aug 20 '18 06:08

Zar E Ahmer


People also ask

Why is my touch screen not working on Windows 10?

Since Windows 10 receives updates at least once a week, it is likely that an update broke your touch screen functionality. 1. You can update Windows 10 from the settings app. To do that, press Win + I to open the Settings app. In the Settings app, go to "Update and Security" and then to "Windows Update".

How to turn off touch screen on Windows 10?

1 First, open the start menu, search for “Device Manager” and open it. 2 In the device manager, expand the “Human Interface Devices” tree, find your touch screen device, right-click on it, and select the “Disable” option. 3 You might see a warning message, click on the “Yes” or “Continue” button to move forward. More items...

How to reinstall touch screen driver in Windows 10?

As such, reinstalling the touch screen driver in Windows 10 is pretty easy. 1. First, open the start menu, search for “Device Manager” and open it. 2. Now, expand the “Human Interface Devices” tree, find your touch screen device, right-click on it, and select the “Uninstall device” option. 3. You will see a warning message.

Will the HP simple pass/touch control shutdown in Windows 1?

HP Simple Pass/ Touch Control will not shutdown in Windows 1... Options Mark Topic as New Mark Topic as Read Float this Topic for Current User Bookmark Subscribe Mute Printer Friendly Page Create an account on the HP Community to personalize your profile and ask a question


1 Answers

You can't do that on the same view I'm afraid, because the touch event either enters to your view, or it does not. Whether you're using intercept, returning false etc... They all depend on whether the event actually reaches your view, and even then, returning false wouldn't pass the event to the below screen, because they are different processes. In your case, the event wouldn't reach your window, and that would mean you can't handle the event at all.

I'm not entirely sure what the parent does, I believe you're trying to move the circle view here after touching it, with a drag operation or some sort. So, I'll give an example approach on how you can do it.

Adding the view in left and right corner can be specified in the layout params you are creating. For instance, top-left would look like this:

params.x = 0;
paramx.y = 0;

Top-right would look like this:

WindowManager manager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);

Point size = new Point();

// Get the screen dimensions here
manager.getDefaultDisplay().getSize(point);
int screenWidth = point.x;

// Assuming your view has a 40 dp width and height,
// calculate its pixel variant
int circleWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DP, 40, getResources().getDisplayMetrics());

// Target the top-right corner of the screen.
params.x = screenWidth - circleWidth;

// Y coordinate would be 0.
params.y = 0;

And view parameters would look like this:

// Assuming your view has a 40 dp width and height,
// calculate its pixel variant
int circleSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DP, 40, getResources().getDisplayMetrics());

WindowManager.LayoutParams params = new WindowManager.LayoutParams(circleSize /* width */, 
circleSize /* height */,
 0 /* x */,
 0 /* y */,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY /* windowType */,
 WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH /* outsideTouch */,
 PixelFormat.TRANSLUCENT /* format */);

After that, moving the view would actually require to change your layout params and updating the view layout. In your onTouchEvent you can do something like this:

// Assuming you know the new x and y values of the view, you can
// update the layout params of the view like this:
((WindowManager.LayoutParams) getLayoutParams()).x = targetX;
((WindowManager.LayoutParams) getLayoutParams()).y = targetY;

// To update the view, you need to either call requestLayout() or
// do it from window manager directly.

// If the first way doesn't work, 2nd will work.

// First way:
requestLayout();

// Second way:

// This will get the same window manager the service has.
WindowManager manager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);

// Update the view layout afterwards.
manager.updateViewLayout(this, getLayoutParams());

That way, you can move the view with the touch event.

Couple things to note:

  1. If you can capture the onTouchEvent you know that you've touched the circle, so you don't need to perform coordinate checks by using the raw values (I'm referring to isPointInside() function). Returning true from all of them will help you receive all the events, but that's not necessary. You probably know how the lifecycle works anyway.
  2. Each circle must be added to the window manager as root with WindowManager.addView() so that the touches do not interfere each other, and touching a point where circle is not in will pass the event to the below screen.

This would be a start for your requirement, and I think you can fit this with your needs.

like image 144
Furkan Yurdakul Avatar answered Oct 16 '22 18:10

Furkan Yurdakul