我有一个启动系统覆盖的服务。当覆盖层可见时,我希望它可触摸/检测触摸,但我想保留与其后面的屏幕的交互(后面是指底层活动,例如覆盖层旁边的活动)。
我的叠加层是 128x128px 的位图/PNG。它被绘制出来,当我点击它时,我收到了触摸!日志,这很好。 而且当我点击屏幕的任何其他部分(除了覆盖层)时,我也会得到触摸!日志并且无法与其下方的屏幕进行交互。
这是我的代码部分:
启动服务的主要 Activity
buttonStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// start Service and return to Homescreen
Intent i = new Intent(MainActivity.this, MyService.class);
startService(i);
Intent newActivity = new Intent(Intent.ACTION_MAIN);
newActivity.addCategory(Intent.CATEGORY_HOME);
newActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newActivity);
}
});
服务/显示叠加
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
myOverlay = new Overlay(MyService.this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(myOverlay, params);
myOverlay.setAnimation(new Waiting(MyService.this, 0, 0));
myOverlay.postInvalidate();
return super.onStartCommand(intent, flags, startId);
}
叠加
public MyOverlay(Context context) {
super(context);
this.context = context;
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("TOUCH!", event.getAction() + ", x:"+event.getX()+", y:"+event.getY());
return false;
}
});
}
我做错了什么?还尝试了 WindowManager.LayoutParams.TYPE_PHONE 而不是 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,但行为相同。
我没有使用标志 FLAG_WATCH_OUTSIDE_TOUCH,那么为什么触摸没有在覆盖层旁边注册?
编辑
看来我已经找到问题了,但还是不知道如何解决... 覆盖层中显示的图像非常小,这不是问题,但覆盖层本身是全屏的(!)
我将以下日志添加到 Overlay / onTouch() 事件中:
Log.i("TOUCH!", "View: "+v.toString() +", size="+ v.getWidth()+"/"+v.getHeight());
然后告诉我查看:package.overlay.myOverlay,size=480/762
现在我尝试通过在服务中添加以下行来强制它不全屏:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
myOverlay = new Overlay(MyService.this);
//HERE
myOVerlay.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(myOverlay, params);
myOverlay.setAnimation(new Waiting(MyService.this, 0, 0));
myOverlay.postInvalidate();
return super.onStartCommand(intent, flags, startId);
}
但这没有帮助... myOverlay 的大小仍然是 480x762...为什么它那么大,我怎样才能让它具有所包含图像的大小?
这对我有用:
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.type = WindowManager.LayoutParams.TYPE_TOAST;
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
将
View
添加到 WindowManager
时使用此 LayoutParams,它会阻止它接收任何点击,可能 TYPE_TOAST
就足够了,但我添加了标志只是为了确保。
我也遇到了同样的问题,我通过设置 params.width 和 params.height 解决了问题。 试试这个。
params.width = 128;
params.height = 128;
希望对你有帮助。
val overlayParams = WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, // Set this flag
PixelFormat.TRANSPARENT
)
我遇到了同样的问题,只需尝试将其添加到您的代码中:
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY
我非常有信心代码能够正常工作,如果它不仅仅检查代码是否存在其他错误,而且就触摸而言,这就是您的解决方案。无论如何,请告诉我。我差点忘了第二部分,只需将属性更改为 matchparent 而不是wrappcontent。
祝你好运