ほとんどの場合、全画面表示にする必要があるアプリがあります。アラートが表示されたり、他のウィンドウが表示されたりすると、アクティビティウィンドウの上部にある全画面が一時的に削除されることを知っています。残念ながら、EditTextなどにソフトキーボードが表示されている場合、ユーザーがキーボードを使い終えると、全画面没入モードは復元されません。
これをどのように達成できるか考えていますか?
Googleによるこのサンプルアプリ から取得した場合、これをアクティビティの最後の最後の終了ブラケットの前に追加する必要があります。
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
// When the window loses focus (e.g. the action overflow is shown),
// cancel any pending hide action. When the window gains focus,
// hide the system UI.
if (hasFocus) {
delayedHide(300);
} else {
mHideHandler.removeMessages(0);
}
}
private void hideSystemUI() {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_LOW_PROFILE |
View.SYSTEM_UI_FLAG_IMMERSIVE
);
}
private void showSystemUI() {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
);
}
private final Handler mHideHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
hideSystemUI();
}
};
private void delayedHide(int delayMillis) {
mHideHandler.removeMessages(0);
mHideHandler.sendEmptyMessageDelayed(0, delayMillis);
}
そして、あなたは良いはずです。 :)
AppCompatActivityを新しいクラス(ImmersiveAppCompatActivity)に拡張することをお勧めします。これにより、このクラスを使用して作成するアクティビティには、没入モードの処理が組み込まれます。
ソフトキーボードが表示された後、イマーシブモードをすばやく設定しようとすると、非表示になりません。
また、静的ハンドラーに切り替えることでハンドラーが改善されたことにも注意してください。これにより、GUIが非表示になる前にユーザーがアクティビティを離れた場合のリークが防止されます。
public abstract class ImmersiveAppCompatActivity extends AppCompatActivity {
private HideHandler mHideHandler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// create a handler to set immersive mode on a delay
mHideHandler = new HideHandler(this);
}
@Override
protected void onResume() {
super.onResume();
setToImmersiveMode();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus) {
mHideHandler.removeMessages(0);
mHideHandler.sendEmptyMessageDelayed(0, 300);
}
else mHideHandler.removeMessages(0);
}
private void setToImmersiveMode() {
// set to immersive
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
private static class HideHandler extends Handler {
private final WeakReference<ImmersiveAppCompatActivity> mActivity;
HideHandler(ImmersiveAppCompatActivity activity) {
mActivity = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
ImmersiveAppCompatActivity activity = mActivity.get();
if(activity != null) activity.setToImmersiveMode();
}
}
}
Kotlinのバージョンは次のとおりです。
abstract class ImmersiveAppCompatActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
setToImmersiveMode()
}
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
val runnable = Runnable { setToImmersiveMode() }
val handler = Handler(Looper.getMainLooper())
handler.postDelayed(runnable, 300)
}
private fun setToImmersiveMode() {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
}
}
次に、このクラスを使用してアクティビティを作成します。
public class SettingsActivity extends ImmersiveAppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(Android.R.id.content, new SettingsFragment()).commit();
}
}
これをAndroid 5.1および7.0でテストして、アクションバーのないフルスクリーンアプリで動作するようにしました。
さらに、EditTextでキーボードを使用する場合は、imeOptionsに注意してください。横長モードでは、奇妙な全画面編集動作が発生する可能性があります。これは、クラスEditorInfoに含まれるimeOptionsフラグを設定することで無効にできます。
<EditText
Android:layout_width="@dimen/pin_width"
Android:layout_height="wrap_content"
Android:inputType="numberPassword"
Android:imeOptions="flagNoExtractUi"
Android:ems="10"
Android:id="@+id/editTextPIN"
Android:textSize="@dimen/pin_large_text_size"/>
https://developer.Android.com/reference/Android/view/inputmethod/EditorInfo.html
このコードをonCreate()に配置して、レイアウトの変更を監視します
getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect rect = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
int screenHeight = getWindow().getDecorView().getRootView().getHeight();
int keyboardHeight = screenHeight - rect.bottom;
if (keyboardHeight > screenHeight * 0.15) {
setToImmersiveMode();
}
}
});
private void setToImmersiveMode() {
// set to immersive
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
これは通常の動作です。ただし、次の2つの手順で修正できます。
1。キーボードが非表示になったときに確認する
2。没入型フルスクリーンモードを設定します(ここでも)
ステップ1は少しトリッキーです。ここで私の答えをチェックできます:
https://stackoverflow.com/a/27567074/2525452
ステップ2は簡単です。
public static void setImmersiveMode( Activity activity )
{
// Get the Activity's content View
ViewGroup content = (ViewGroup) activity.findViewById( Android.R.id.content );
//
// Set the immersive mode flags at the content View
content.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
);
}