У меня есть класс, расширенный от 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
Моя цель - показать это представление на экране блокировки, чтобы пользователю потребовалось несколько секунд по сравнению с другими приложениями, но поскольку он имеет только прямоугольную рамку с размером штриха вокруг экрана и ничего другого в центральной части, которая остается пустой или прозрачной и отображается правильно, но также он потребляет мои сенсорные события.
Как и всякий раз, когда это представление отображается на экране, оно потребляет события касания, и пользователь чувствует, что телефон повешен на несколько секунд.
Я хочу отключить сенсорное прослушивание для этого представления и, что наиболее важно, передать все события касания на любой экран ниже, как будто пользователь обычно использует его всякий раз, когда появляется это представление.
Что пробовал:
Если кто сможет разобраться в этом деле. Заранее спасибо.
Вы можете попробовать сначала установить 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);
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 должно решить вашу проблему.
Я бы посоветовал: 1) Поместите несколько журналов в методы касания в вашем представлении, чтобы убедиться, что они вызываются и какие события они получают. 2) Сделайте вид меньше и убедитесь, что вы можете щелкнуть за его пределами, 3) поместите представление в отдельный проект с (нормальным) действием и убедитесь, что оно работает так, как вы ожидаете, 4) считаете, что анимация может влиять на кликабельность?