[Android] 휴대폰 하단 시스템 네비게이션 바(뒤로가기, 홈, 최근 앱 버튼이 있는 바)를 숨기는 방법
앱 하단의 시스템 네비게이션 바를 숨기고 전체 화면(몰입 모드, Immersive Mode)으로 만들려면, 액티비티의 Window
객체를 통해 시스템 UI 관련 플래그를 설정해야 한다.
앱의 Activity
(예: MainActivity.java
또는 앱 전체에 적용하려면 BaseActivity
)의 onCreate
또는 onResume
메소드, 혹은 사용자가 특정 버튼을 눌렀을 때 등 원하는 시점에 아래 코드를 추가하여 시스템 UI를 숨길 수 있다.
최신 방식 (Android 11 이상 권장, 하위 호환 지원): WindowInsetsControllerCompat
사용
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.core.view.WindowInsetsControllerCompat;
// Activity 내에서
private void hideSystemUI() {
WindowCompat.setDecorFitsSystemWindows(getWindow(), false); // 앱 콘텐츠를 시스템 바 영역까지 확장
WindowInsetsControllerCompat controller = WindowCompat.getInsetsController(getWindow(), getWindow().getDecorView());
if (controller != null) {
// 시스템 바 (상태 표시줄, 네비게이션 바) 숨기기
controller.hide(WindowInsetsCompat.Type.systemBars());
// 화면 가장자리를 스와이프해야 시스템 바가 잠시 나타나도록 설정
controller.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
}
}
// 시스템 UI를 다시 보이게 하려면
private void showSystemUI() {
WindowCompat.setDecorFitsSystemWindows(getWindow(), true); // 앱 콘텐츠 영역 복원
WindowInsetsControllerCompat controller = WindowCompat.getInsetsController(getWindow(), getWindow().getDecorView());
if (controller != null) {
// 시스템 바 다시 표시
controller.show(WindowInsetsCompat.Type.systemBars());
}
}
// 예시: onCreate에서 호출
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView 이후 또는 전에 호출 가능
hideSystemUI();
// ...
}
// 예시: 화면 터치 시 UI 토글
// @Override
// public void onWindowFocusChanged(boolean hasFocus) {
// super.onWindowFocusChanged(hasFocus);
// if (hasFocus) {
// hideSystemUI();
// }
// }
getWindow()
는 Activity 또는 Dialog 안에서만 정상적으로 쓸 수 있다.
Context만 있는 클래스에서는 getWindow()
사용할 수 없다.
import androidx.core.view.WindowCompat;
public class MyActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
}
}
만약 현재 클래스가 Activity가 아니면?
Context
만 가지고 있으면getWindow()
를 쓸 수 없다Activity
를 받아와야 한다.
예시 (Context → Activity 변환해서 사용하는 방법):
if (context instanceof Activity) {
Activity activity = (Activity) context;
WindowCompat.setDecorFitsSystemWindows(activity.getWindow(), false);
}
이전 방식 (Android 11 미만): System UI Visibility Flags 사용
import android.view.View;
// Activity 내에서
private void hideSystemUI_Legacy() {
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY // 스와이프 시 잠시 보임
| 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; // 상태 표시줄 숨기기
decorView.setSystemUiVisibility(uiOptions);
}
// 시스템 UI를 다시 보이게 하려면
private void showSystemUI_Legacy() {
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
// 예시: onCreate에서 호출
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
hideSystemUI_Legacy();
// ...
}
주의할점
하위 호환성: 최신 앱에서는 WindowInsetsControllerCompat
사용이 권장됨. 이 API는 내부적으로 이전 버전과의 호환성을 처리해 준다.
호출 시점:onCreate
에서 호출하면 액티비티 시작 시부터 적용됨. 사용자가 특정 액션을 취했을 때 숨기거나 보이게 할 수도 있다.
테마: 앱의 테마가 .NoActionBar
이면서 전체 화면 관련 속성(windowTranslucentNavigation
등)이 설정되어 있으면 동작에 영향을 줄 수 있다.
Fragment 내에서 호출
getWindow()
메소드는 Activity
클래스에 속해 있습니다. 만약 이 코드를 Fragment 안에서 사용하려고 하셨다면, 직접 getWindow()
를 호출할 수 없기 때문에 빨간색으로 표시될 수 있다.
Fragment 내에서 시스템 UI를 제어해야 한다면, Activity
의 Window
객체에 접근해야 한다. requireActivity().getWindow()
또는 getActivity().getWindow()
(null 체크 필요)를 사용
// Fragment 클래스 내부
import android.view.Window;
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.core.view.WindowInsetsControllerCompat;
// ...
private void hideSystemUIFromFragment() {
// Fragment에서는 requireActivity() 또는 getActivity() 사용
if (getActivity() != null) {
Window window = requireActivity().getWindow(); // 또는 getActivity().getWindow()
WindowCompat.setDecorFitsSystemWindows(window, false);
WindowInsetsControllerCompat controller = WindowCompat.getInsetsController(window, window.getDecorView());
if (controller != null) {
controller.hide(WindowInsetsCompat.Type.systemBars());
controller.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
}
}
}
private void showSystemUIFromFragment() {
if (getActivity() != null) {
Window window = requireActivity().getWindow(); // 또는 getActivity().getWindow()
WindowCompat.setDecorFitsSystemWindows(window, true);
WindowInsetsControllerCompat controller = WindowCompat.getInsetsController(window, window.getDecorView());
if (controller != null) {
controller.show(WindowInsetsCompat.Type.systemBars());
}
}
}