반응형 디자인
유연한 레이아웃(Flexible Layout)
- 화면 크기에 따라 너비나 높이가 유동적으로 변하는 구조
안전 영역(Safe Area)
- 노치 디자인이나 하단 바에 UI가 가려지지 않도록 보호하는 영역
적응형 UI(Adaptive UI)
- 스마트폰, 태블릿, 폴더블폰 등 기기 유형에 따라
레이아웃 구조 자체가 바뀌는 설계
예) 반응형 웹
사용자 경험(UX) 원칙
디자인 가이드라인 없이도 지켜야 할 최소한의 규칙
시각적 계층 구조
- 중요한 정보는 크게, 진하게 배치하여 사용자의 시선을 유도
피드백(Affordance)
- 버튼을 눌렀을 때 색이 변하거나 진동이 오는 등, 동작이 수행됨을 알려야 함
일관성(Consistency)
- 앱 전체에서 확인 버튼의 위치나 뒤로가기 동작이 일관되어야 함
접근성(Accessibility)
- 저시력자나 색약 사용자를 위해 충분히 대비와 텍스트 크기 고려
- 이미지의 경우 contentDescription을 제공하여 시각장애인 고려
모바일 앱 UI 계층구조
컴포넌트(Component)
- UI를 구성하는 최소 단위
- Button, Text Image 등
레이아웃(Layout)
- 컴포넌트들을 화면에 배치하는 규칙
- 가로/세로 정렬, 여백, 중첩
- Row, Column, Box
컨테이너(Container)
- 앱의 기본적인 뼈대, 또는 시각적 효과를 위해
여러 컴포넌트를 하나로 묶어 관리하는 단위
- Scaffold: 앱의 기본적 뼈대
- Surface: 컴포넌트를 감싸고 배경 색, 테두리, elevation 등을 부여

안드로이드 View의 계층구조

모바일 앱 UI 패러다임 변화
명령형(Imperative)에서 선연형(Declarative)으로
모바일 UI 프레임워크 패러다임 변화
명령형 UI
- "버튼의 색을 빨갛게 바꾸고, 텍스트를 확인으로 변경하라"와 같이
상태 변화에 따른 UI의 변경 과정을 일일이 코딩
- Android XML 레이아웃 방식
선언형 UI
- UI 상태(State)를 정의, "UI 상태가 완료라면 버튼은 빨간색이고
텍스트는 확인이다" 라고 UI 선언을 작성
- 프레임워크가 UI 상태 변화를 감지하면
자동으로 UI 선언에 따라 화면을 다시 그림
- 안드로이드 Jetpack Compose에서 UI 선언은 Composable(함수)로 작성함
- Jetpack Compose, Flutter
- UI는 상태의 함수, UI = f(state)
안드로이드 앱 UI 패러다임 변화

안드로이드 View 방식
- 안드로이드 처음부터 있었던 UI 작성 방식
- 컴포넌트, 레이아웃은 모두 View를 상속
컴포넌트
- 정보를 출력, 입력 받기 위한 UI 구성 요소
- TextView, Button EditText, Checkbox 등
레이아웃
- 사용자 인터페이스에 대한 시각적 형태를 계층적 구조로 정의
- XML 파일로 작성하고, 소스 코드에서 로드하여 사용함
컴포넌트도 XML에 함께 작성함
- LinearLayout, ConstraintLayout, FrameLayout, MotionLayout 등

View 클래스
- 화면에 표시 가능한 사각형 영역
- 각각의 뷰는 알아서 자신의 내용을 그리고, 이벤트(키보드, 마우스) 처리 해결
- ViewGroup은 View이지만 다른 View를 포함할 수 있는 View
레이아웃은 ViewGroup에 속함
- UI 컴포넌트, 레이아웃 모두 View를 상속하여 구현
- View의 속성이 곧 컴포넌트, 레이아웃의 속성이 됨
Composable Function
데이터를 인자로 받아 UI를 표시하는 함수
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
Greeting(name = "compose")
}
}
}
}
@Composable
fun Greeting(name: String = "compose") {
Text(text = "Hello $name!")
}
- Jetpack Compose에서 UI를 선언형으로 기술하는 함수
- 복잡한 레이아웃 등의 UI 요소를 생성하는 함수
- 다른 Composable function 내에서만 호출 가능
- 상태(State)를 가질 수 있음
상태가 바뀌면 composable function은 recomposition에 의해 다시 실행
composition: Composable 함수가 처음 실행되어 UI를 그리는 것
recomposition: 상태가 변경되었을 때 UI를 다시 그리는 것
작성 시 주의사항
- 이름은 대문자로 시작하며, 명사형으로 정의
- @Composable annotation을 붙여야 함
- pure function으로 만들어야 함
레이아웃(Layout)

Modifier
- 컴포넌트의 크기, 레이아웃, 모양, 클릭 이벤트 등을 결정
호출 순서에 따라 결과가 다를 수 있음
@Composable
fun Greeting() {
Row (modifier = Modifier.padding(8.dp)){
Box {
Image(painter = painterResource(id = R.drawable.android), contentDescription = null)
Icon(Icons.Filled.Check, contentDescription = "Check mark",
modifier = Modifier.align(Alignment.BottomEnd))
}
Spacer(modifier = Modifier.padding(16.dp))
Column {
Text(text = "First Text")
Text(text = "Second Text", fontSize = 20.sp, fontWeight = FontWeight.Bold)
}
}
}
dp와 sp 단위
dp(Density-independent Pixels)
- 기기의 화면 밀도(DPI)에 상관없이 항상 동일한 물리적 크기 유지
sp(Scale-independent Pixels)
- 사용자의 시스템 글꼴 크기 설정에 따라 크기가 가변적으로 변하는 단위
- dp로 텍스트 크기를 고정하면 설정을 바꿔도 글자 크기가 변하지 않음
슬롯 기반 레이아웃(컨테이너)
- UI 컨테이너에 빈 공간을 남겨두어(슬롯)
개발자가 원하는대로 채울 수 있게 함
- 대표적으로 Scaffod
@preview
- 안드로이드 스튜디오에서
@Preview annotation을 사용하여
애뮬레이터를 사용하지 않고도 UI를 실시간으로 확인