4_화면 구성

topics 500-모바일개발 502 Android
types 이론 학습
tags
references freehoon.tistory.com/24 brunch.co.kr/@zalhanilll/407 hongbeomi.medium.com/appcompatactivit...

Android UI 구성

Android에서 화면을 구성하는 방법을 정리한다.

기본 개념

  • 화면은 Activity로 구성한다
  • 모든 앱에 화면이 있는 건 아니다 (백그라운드 앱도 있음)
  • 화면과 Activity가 1:1 대응되는 건 아니다
    • Fragment나 Compose를 사용하면 하나의 Activity에서 여러 화면 가능

화면 구성 방법

1. Kotlin 코드로 구현

import android.graphics.Typeface
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Gravity
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // TextView 생성
        val name = TextView(this).apply {
            typeface = Typeface.DEFAULT_BOLD
            text = "Lake Louise"
        }

        // ImageView 생성
        val image = ImageView(this).also {
            it.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.lake_1))
        }

        // 또 다른 TextView
        val address = TextView(this).apply {
            typeface = Typeface.DEFAULT_BOLD
            text = "Lake Louise, AB, 캐나다"
        }

        // LinearLayout으로 묶기
        val layout = LinearLayout(this).apply {
            orientation = LinearLayout.VERTICAL
            gravity = Gravity.CENTER
            addView(name, WRAP_CONTENT, WRAP_CONTENT)
            addView(image, WRAP_CONTENT, WRAP_CONTENT)
            addView(address, WRAP_CONTENT, WRAP_CONTENT)
        }

        setContentView(layout)
    }
}

apply vs also: applythis로 접근, alsoit으로 접근한다. 마지막 인자가 람다면 소괄호 밖으로 뺄 수 있다.

2. XML로 구현 (권장)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:text="Lake Louise" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/lake_1" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:text="Lake Louise, AB, 캐나다" />
</LinearLayout>

Activity에서 연결:

setContentView(R.layout.activity_main)

왜 XML을 쓰냐면: UI 코드와 로직 코드가 분리되어 가독성이 좋다. 디자이너와 협업도 쉽다.

View 클래스 구조

|600

클래스 설명
View 모든 뷰의 최상위 클래스
ViewGroup 다른 뷰를 묶어서 제어 (레이아웃 담당)
TextView 텍스트 출력
ImageView 이미지 출력
Button 버튼
EditText 텍스트 입력

참고: Activity는 View의 서브클래스만 화면에 출력할 수 있다.

ViewGroup (레이아웃)

레이아웃 설명
LinearLayout 선형 배치 (Flutter의 Row/Column)
RelativeLayout 상대적 배치
FrameLayout 단일 뷰 또는 뷰 겹치기
GridLayout 행/열 기반 정렬
ConstraintLayout 복잡한 UI (권장)
<!-- LinearLayout 예시 -->
<LinearLayout
    android:orientation="vertical"
    android:gravity="center">
    <!-- 자식 뷰들 -->
</LinearLayout>

주요 속성

기본 속성

속성 설명 예시
id 뷰 식별자 @+id/myView
layout_width 너비 match_parent, wrap_content, 100dp
layout_height 높이 match_parent, wrap_content, 100dp
layout_margin 외부 여백 16dp
padding 내부 여백 8dp

ID 사용법

<TextView
    android:id="@+id/textName"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
// 기존 방식
val textView = findViewById<TextView>(R.id.textName)

// ViewBinding (권장)
// build.gradle에서 viewBinding.isEnabled = true 설정 필요
val binding = ActivityMainBinding.inflate(layoutInflater)
binding.textName.text = "Hello"

왜 ViewBinding을 쓰냐면: 타입 안전하고, null 체크가 필요 없다. findViewById는 실수하면 런타임에 터진다.

크기 관련

설명
match_parent 부모 크기에 맞춤
wrap_content 내용 크기에 맞춤
layout_weight 남은 공간 비율로 채움 (Flutter의 Expanded)
<!-- weight 예시: 1:2 비율 -->
<LinearLayout android:orientation="horizontal">
    <View android:layout_weight="1" android:layout_width="0dp" />
    <View android:layout_weight="2" android:layout_width="0dp" />
</LinearLayout>

visibility

설명
visible 보임
invisible 안 보이지만 자리 차지
gone 안 보이고 자리도 안 차지

텍스트 관련

속성 설명
text 출력할 문자열
textColor 글자 색상
textSize 글자 크기 (sp 권장)
textStyle bold, italic, normal
maxLines 최대 줄 수
ellipsize 초과 시 ... 위치 (start, middle, end)
inputType EditText 입력 타입 (phone, text 등)
<TextView
    android:text="Hello World"
    android:textColor="@color/black"
    android:textSize="16sp"
    android:textStyle="bold"
    android:maxLines="2"
    android:ellipsize="end" />

|300

단위 비교

단위 설명
px 픽셀 (비권장)
dp 밀도 독립적 픽셀 (레이아웃에 사용)
sp 확장 가능한 픽셀 (텍스트에 사용, 사용자 설정 반영)

왜 sp를 쓰냐면: 사용자가 시스템 설정에서 글꼴 크기를 변경하면 sp로 지정한 텍스트도 같이 커진다. 접근성을 위해 텍스트는 sp를 쓴다.

관련 문서