Pass Touch Events to Screen below current view - Android

3.2k Views Asked by At

I have a class extended from View

public class SideLightView extends View {
...
...
...
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    width = getWidth();
    height = getHeight();

    if (GlobalValues.DEBUG_MODE) Log.e(TAG, "Screen Width : " + width + "  
    Height : " + height);

    paint.setAntiAlias(true);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(strokeWidth);
//        paint.setColor(color);

    path.moveTo(0, 0);
    path.lineTo(0, height);
    path.lineTo(width, height);
    path.lineTo(width, 0);
    path.lineTo(0, 0);

    paint.setShader(new LinearGradient(0, 0, 0, height, top_color, 
    bottom_color, Shader.TileMode.CLAMP));
    canvas.drawPath(path, paint);

}

@Override
public boolean onTouchEvent(MotionEvent event) {
//        super.onTouchEvent(event);
    return false;
}

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
//        super.dispatchTouchEvent(event);
    return false;
}
}

I am adding this view in a service class using Window Manager like below :

mWindowManager = (WindowManager) mContext.getSystemService(WINDOW_SERVICE);


    int LAYOUT_FLAG;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;  
// for solving error window type 2006
    } else {
        LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;  // for solving 
error window type 2038
    }

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT,
            LAYOUT_FLAG,
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
//                        | WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            PixelFormat.TRANSPARENT);


    params.gravity = Gravity.LEFT;


    sideLightView = new SideLightView(mContext);
    sideLightView.setClickable(false);
    sideLightView.setFocusable(false);

    mWindowManager.addView(sideLightView, params);
    Animation fade_in_out_animation = AnimationUtils.loadAnimation(mContext, 
R.anim.fade_in_and_out);
    fade_in_out_animation.setDuration(800);

    sideLightView.setStrokeWidth(40);

    sideLightView.startAnimation(fade_in_out_animation);

    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            removeView();
        }
    }, utility.getSideLigthDuration() * 1000); //adding 3 sec delay

My aim is to show this view on lock screen for user required seconds over the other apps, but as it has only a rectangular frame of stroke size around the screen and totally nothing else in centre part which remains empty or transparent and it displays correctly but also it consumes my touch events.

As whenever this view is displayed over the screen it consumes touch events and the user feels like the phone hanged for a few seconds.

I want to disable touch listening for this view, and most importantly pass all the touch events to whatever the screen below is as like user is using normally whenever this view appears

What things I tried :

  • I override onTouchEvent and dispatchTouchEvent methods of the view and returned false for it - no change.
  • returned true for both the overriden methods - no change
  • I setClickable and Focusable to false - no change
  • I tried removing and adding the flags : FLAG_NOT_TOUCH_MODAL , FLAG_NOT_FOCUSABLE , FLAG_WATCH_OUTSIDE_TOUCH - no change

If anyone can figure out this case. Thanks in advance.

2

There are 2 best solutions below

0
On BEST ANSWER
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
            WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
            PixelFormat.TRANSPARENT);

Add WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE flag should solve your problem.

1
On

You can try to first set focusable= "false" and enabled="false for parent layout.

Now, implement OnTouchListener over your child view, and upon receiving Touch Event just return true from child.

child_view.setOnTouchListener(new OnTouchListener(){

    @Override
    public boolean onTouch(View arg0, MotionEvent arg1) {
        // your code here.
              return true;
        }
    });