我有这个自定义视图,它作为系统警报添加到 WindowManager,它应该用作全屏覆盖,以在应用程序运行时阻止手机的某些部分。
当覆盖显示它会阻塞电话窗口全屏时,这非常有用。现在我想支持旋转更改。
这部分也可以正常工作,我有 3 个布局文件,layout
layout-land
当layout-h600dp-land
我旋转手机时,它会更改为正确的布局。我遇到的问题是在onConfigurationChanged(Configuration newConfig)
调用之后,我再次膨胀布局,所有点击侦听器都消失了,因此视图中的任何按钮都不会对点击做出反应。当我点击按钮时,按钮的按下状态会发生变化,但没有触发任何 onClickListeners。在方向改变之前,所有按钮都可以工作。我一直在使用 Butterknife 来减少 onClicklisteners 和 findViewById 的样板代码,但我已经将其更改为 findViewById 并在视图上手动添加 clicklistener,这并没有什么区别。
现在是一些代码。该服务将视图添加到窗口管理器
public class OverlayService extends Service {
public void showOverlay() {
startForeground();
mUiHandler.post(new Runnable() {
@Override
public void run() {
if (!DrivingOverlay.isShowing()) {
if (mOverlay == null) {
mOverlay = new Overlay(OverlayService.this);
mOverlay.setTag(OVERLAY_TAG);
mOverlay.setId(R.id.overlay);
}
addView(mOverlay);
}
});
}
private void addView(@NonNull final View view) {
try {
final WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
windowManager.addView(view, Overlay.LAYOUT_PARAMS);
} catch (IllegalStateException error) {
Log.e(TAG, Log.getStackTraceString(error));
}
}
}
作为叠加层的自定义视图。
public class Overlay extends FrameLayout {
private static boolean sIsOverlayShowing;
public static final WindowManager.LayoutParams LAYOUT_PARAMS = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
public Overlay(Context context) {
super(context);
init(context);
}
public Overlay(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public Overlay(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public Overlay(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
protected void init(Context context) {
inflate(context, R.layout.driving_overlay, this);
if (!isInEditMode()) {
ButterKnife.bind(this);
}
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(TAG, "onConfigurationChanged");
init(getContext());
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
setIsOverlayShowing(true);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
setIsOverlayShowing(false);
}
@Override
public void onViewAttachedToWindow(View v) {
setIsOverlayShowing(true);
}
@Override
public void onViewDetachedFromWindow(View v) {
setIsOverlayShowing(false);
}
public static boolean isShowing() {
return sIsOverlayShowing;
}
public static void setIsOverlayShowing(boolean isOverlayShowing) {
sIsOverlayShowing = isOverlayShowing;
}
}