Передача событий касания на экран под текущим представлением - Android

У меня есть класс, расширенный от 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;
}
}

Я добавляю это представление в класс обслуживания с помощью диспетчера окон, как показано ниже:

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

Моя цель - показать это представление на экране блокировки, чтобы пользователю потребовалось несколько секунд по сравнению с другими приложениями, но поскольку он имеет только прямоугольную рамку с размером штриха вокруг экрана и ничего другого в центральной части, которая остается пустой или прозрачной и отображается правильно, но также он потребляет мои сенсорные события.

Как и всякий раз, когда это представление отображается на экране, оно потребляет события касания, и пользователь чувствует, что телефон повешен на несколько секунд.

Я хочу отключить сенсорное прослушивание для этого представления и, что наиболее важно, передать все события касания на любой экран ниже, как будто пользователь обычно использует его всякий раз, когда появляется это представление.

Что пробовал:

  • Я переопределил методы представления onTouchEvent и dispatchTouchEvent и вернул для него false - без изменений.
  • вернул истину для обоих методов переопределения - без изменений
  • Я установил для Clickable и Focusable значение false - без изменений
  • Я попытался удалить и добавить флаги: FLAG_NOT_TOUCH_MODAL, FLAG_NOT_FOCUSABLE, FLAG_WATCH_OUTSIDE_TOUCH - без изменений

Если кто сможет разобраться в этом деле. Заранее спасибо.

Я бы посоветовал: 1) Поместите несколько журналов в методы касания в вашем представлении, чтобы убедиться, что они вызываются и какие события они получают. 2) Сделайте вид меньше и убедитесь, что вы можете щелкнуть за его пределами, 3) поместите представление в отдельный проект с (нормальным) действием и убедитесь, что оно работает так, как вы ожидаете, 4) считаете, что анимация может влиять на кликабельность?

Nerdy Bunz 16.11.2018 11:39
0
1
1 787
2

Ответы 2

Вы можете попробовать сначала установить focusable= "false" и enabled = "false в качестве родительского макета.

Теперь реализуйте OnTouchListener над своим дочерним представлением, и после получения Touch Event просто верните true от дочернего.

child_view.setOnTouchListener(new OnTouchListener(){

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

Я не закодировал родительское представление, и для этого нет файла макета XML. Я просто добавляю непосредственно объект класса SideLightView в windowmanager.addView (объект SideLightView);

Pishang Ujeniya 10.10.2018 20:40
        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);

Добавление флага WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE должно решить вашу проблему.

Другие вопросы по теме