동작 변경사항: Android 16 이상을 타겟팅하는 앱 | Android Developers
Android 16 이상을 타겟팅하는 앱에 영향을 미치는 Android 16의 변경사항을 알아봅니다.
developer.android.com

이번 Android 16에서 최소 너비가 600dp 이상인 디스플레이에서 앱의 orientation, resizability, aspect ratio 제한이 자동으로 무시된다.
너무 폭력적인 정책이다;;;
Android 15 이하(Before)
<activity
android:name=".MainActivity"
android:screenOrientation="portrait">
</activity>
위 설정은 모든 기기에서 세로 모드만 강제했다.
Android 16 이상 (After)
<activity
android:name=".MainActivity"
android:screenOrientation="portrait"> <!-- 태블릿에서는 무시됨 -->
</activity>
태블릿이나 폴더블의 큰 화면에서는 이 설정이 자동으로 무시 된다.
이번 변경사항 Google의 철학은 "큰 화면에서는 가로 모드도 지원해야 한다" 는 것이다.
해결 방법: 동적 방향 설정 (Dynamic Orientation)
이 문제를 해결하려면 매니페스트의 고정 설정 대신 런타임에 동적으로 방향을 설정해야 한다.
Step 1: AndroidManifest.xml 수정
<activity
android:name=".MainActivity"
android:exported="true"
android:configChanges="orientation|screenSize"
android:theme="@android:style/Theme.Material.Light.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
중요한 부분:
- ❌ android:screenOrientation="portrait" 제거 (또는 설정하지 않음)
- ✅ android:configChanges="orientation|screenSize" 추가
configChanges 속성이 하는 역할
configChanges 속성은 "이 설정들이 변경되면 Activity를 재생성하지 말고, onConfigurationChanged만 호출해줘"라는 뜻이다.
- orientation: 화면 회전
- screenSize: 화면 크기 (폴더블 펼침/닫힘 포함)
이렇게 하면 불필요한 Activity 재생성을 방지하고, 우리가 onConfigurationChanged 콜백에서 직접 방향을 제어할 수 있다.
Step 2: 라이브러리 추가
build.gradle (Module: app)
dependencies {
// Window Size Classes
implementation("androidx.window:window:1.3.0")
}
Window 라이브러리를 사용하여 현재 화면 크기를 감지한다.
Step 3: Activity에서 동적 방향 설정
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import androidx.window.layout.WindowMetricsCalculator
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 앱 시작 시 화면 크기에 따라 방향 설정
setOrientationForScreenSize()
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
// 화면 회전/크기 변경 시 방향 재설정
setOrientationForScreenSize()
}
/**
* 화면 크기를 감지하여 방향을 설정합니다.
* 작은 화면(폰): 세로 고정
* 큰 화면(태블릿): 자유롭게 회전 가능
*/
private fun setOrientationForScreenSize() {
requestedOrientation = if (isCompactScreen()) {
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
} else {
ActivityInfo.SCREEN_ORIENTATION_FULL_USER
}
}
/**
* 현재 화면이 작은 화면(폰)인지 확인합니다.
* @return true: 작은 화면(폰), false: 큰 화면(태블릿)
*/
private fun isCompactScreen(): Boolean {
val metrics = WindowMetricsCalculator.getOrCreate()
.computeCurrentWindowMetrics(this)
val widthDp = metrics.bounds.width() / resources.displayMetrics.density
// 600dp 미만이면 폰으로 간주 (Material Design 기준)
return widthDp < 600
}
}
코드 동작 원리
1. 화면 크기 측정
val metrics = WindowMetricsCalculator.getOrCreate()
.computeCurrentWindowMetrics(this)
val widthDp = metrics.bounds.width() / resources.displayMetrics.density
- WindowMetricsCalculator: 현재 창의 크기를 픽셀 단위로 반환
- 픽셀을 dp로 변환 (밀도로 나눔)
2. Material Design 기준으로 판단
return widthDp < 600 // 600dp가 기준
Material Design 정의:
- Compact: 너비 < 600dp (휴대폰)
- Medium: 600dp ~ 840dp (작은 태블릿)
- Expanded: > 840dp (큰 태블릿)
이 예제에서는 600dp를 기준으로 단순하게 분류했다.
3. 방향 설정
requestedOrientation = if (isCompactScreen()) {
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT // 폰: 세로 고정
} else {
ActivityInfo.SCREEN_ORIENTATION_FULL_USER // 태블릿: 자유로운 회전
}
FULL_USER: 사용자의 회전 잠금 설정을 따른다.
동작 흐름
앱 시작
↓
onCreate() 실행
↓
setOrientationForScreenSize() 호출
↓
isCompactScreen() 판단
↓
폰 (< 600dp) → PORTRAIT 고정
태블릿 (≥ 600dp) → FULL_USER (자유롭게 회전)
---
사용자가 기기를 회전하거나
폴더블을 펼치면
↓
onConfigurationChanged() 호출
↓
setOrientationForScreenSize() 다시 실행
↓
새로운 화면 크기에 맞게 방향 재설정
⚠️ 주의사항
configChanges 설정의 부작용
android:configChanges="orientation|screenSize"
이 설정을 하면:
- ✅ Activity가 재생성되지 않음 (성능 향상)
- ✅ 상태 보존 용이
- ❌ Resources가 자동으로 재로드되지 않음
만약 이미지나 레이아웃이 방향에 따라 달라진다면?
각 폴더에 별도로 관리해야 합니다:
res/
├── layout-land/ // 가로 모드 레이아웃
├── layout-port/ // 세로 모드 레이아웃
├── drawable-hdpi/ // 고해상도 이미지
└── drawable-xhdpi/ // 초고해상도 이미지
또는 onConfigurationChanged에서 수동으로 UI를 업데이트합니다:
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
setOrientationForScreenSize()
// 필요하면 UI 수동 업데이트
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
// 가로 모드 UI 처리
} else {
// 세로 모드 UI 처리
}
}
🎯 언제 이 방법을 사용할까?
추천하는 경우:
- 현재 폰 앱을 태블릿으로 확장 중
- 빠르게 임시 해결책이 필요한 상황
- 큰 화면 지원을 단계적으로 진행 중
권장하지 않는 경우:
- 새로운 앱 개발: 처음부터 Responsive Design으로 개발
- 이미 큰 화면을 지원 중: 별도의 동적 설정 불필요
'Android' 카테고리의 다른 글
| Android Build process 훑어보기 (1) - 빌드, 배포, 컴파일,런타임 (0) | 2024.03.05 |
|---|---|
| RecyclerView (0) | 2023.08.24 |