アプリの実行中に電話の特定の部分をブロックするフルスクリーン オーバーレイとして機能するシステム アラートとして 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;
}
}