View, ViewGroup, ViewStub

aufcl4858·2025년 11월 2일

안드로이드 개발을 하다 보면 View와 ViewGroup이라는 용어를 자주 접하게 된다. 처음에는 이 둘의 차이가 명확하지 않아 헷갈릴 수 있는데, 오늘은 이 두 개념의 차이점과 함께 UI 성능 최적화에 유용한 ViewStub까지 정리해보려고 한다.

View와 ViewGroup이란?

View는 안드로이드 UI의 가장 기본이 되는 구성 요소이다. 화면에 표시되는 모든 UI 요소의 최상위 클래스라고 볼 수 있다. Button, TextView, ImageView 같은 위젯들이 모두 View를 상속받아 만들어진다.

ViewGroup은 View를 상속받은 특수한 클래스로, 다른 View들을 담을 수 있는 컨테이너 역할을 한다. LinearLayout, ConstraintLayout, FrameLayout 등이 대표적인 예이다.

View와 ViewGroup의 주요 차이점

1. 자식 요소 포함 여부

가장 핵심적인 차이는 자식 요소를 가질 수 있느냐 없느냐이다.

  • View: 자식 요소를 가질 수 없다. 트리 구조에서 말하자면 leaf node에 해당한다.
  • ViewGroup: 여러 개의 View나 다른 ViewGroup을 자식으로 포함할 수 있다.

2. 역할과 목적

두 클래스는 UI에서 담당하는 역할이 다르다.

  • View: 실제 콘텐츠를 화면에 표시하고, 사용자의 터치나 클릭 같은 입력을 직접 받는다.
  • ViewGroup: 자식 View들을 어떻게 배치할지 결정하고, 레이아웃을 관리하는 것이 주된 역할이다.

3. 측정 및 레이아웃 프로세스

안드로이드의 렌더링 과정에서도 차이가 있다.

  • View: onMeasure()에서 자기 자신의 크기만 측정하면 된다.
  • ViewGroup: 자신의 크기뿐만 아니라 모든 자식들의 크기를 측정하고, onLayout()에서 각 자식을 어디에 배치할지 결정해야 한다.

4. 그리기 프로세스

화면에 그려지는 방식도 다르다.

  • View: onDraw()에서 자기 자신만 그린다.
  • ViewGroup: 자신을 먼저 그린 후, dispatchDraw()를 통해 모든 자식들을 순서대로 그린다.

5. 제공하는 메서드

ViewGroup은 View를 상속받기 때문에 추가적인 메서드들을 제공한다.

  • View: onDraw(), onMeasure() 등 기본적인 메서드만 가진다.
  • ViewGroup: addView(), removeView(), getChildAt() 등 자식 View를 관리하는 메서드들이 추가로 제공된다.

6. 계층 구조

실제 UI를 구성할 때는 다음과 같은 트리 구조로 만들어진다.

ConstraintLayout (ViewGroup)
├── TextView (View)
├── Button (View)
└── LinearLayout (ViewGroup)
    ├── ImageView (View)
    └── EditText (View)

ViewStub을 활용한 UI 성능 최적화

View와 ViewGroup의 기본 개념을 이해했다면, 이제 성능 최적화를 위한 특별한 View인 ViewStub에 대해 알아보자.

안드로이드 개발을 하다 보면 때때로 조건부로 보여줘야 하는 UI가 있다. 예를 들어 에러 메시지, 로딩 화면, 또는 특정 상황에서만 나타나는 배너 같은 것들이다. 이럴 때 유용하게 사용할 수 있는 것이 바로 ViewStub이다.

ViewStub이란?

ViewStub은 지연 로딩(Lazy Loading)을 위한 가벼운 View이다. 초기에는 실제 View를 생성하지 않고 자리만 차지하고 있다가, 필요한 시점에 inflate되어 실제 레이아웃으로 대체된다.

일반적인 View는 레이아웃이 inflate될 때 함께 생성되지만, ViewStub은 명시적으로 inflate를 호출하기 전까지는 메모리에 로드되지 않는다. 크기도 0이고 화면에 그려지지도 않기 때문에 거의 비용이 들지 않는다.

ViewStub의 주요 특징

  1. 초기 로딩 시 메모리를 거의 사용하지 않음 - 실제 레이아웃이 필요할 때까지 inflate되지 않는다.
  2. 한 번만 사용 가능 - inflate되면 ViewStub 자체는 View 계층에서 제거되고 실제 레이아웃으로 대체된다.
  3. visibility 변경으로도 inflate 가능 - setVisibility(View.VISIBLE)을 호출하면 자동으로 inflate된다.

사용 방법

XML에서 정의:

<ViewStub
    android:id="@+id/stub_error_layout"
    android:layout="@layout/error_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

코드에서 inflate:

// 방법 1: inflate() 메서드 사용
val errorView = findViewById<ViewStub>(R.id.stub_error_layout).inflate()

// 방법 2: visibility 변경
findViewById<ViewStub>(R.id.stub_error_layout).visibility = View.VISIBLE

// inflate 후에는 ViewStub이 제거되므로 실제 View로 접근
val errorLayout = findViewById<View>(R.id.error_layout)

UI 성능 최적화 방법

ViewStub을 사용하면 다음과 같은 방식으로 성능을 최적화할 수 있다.

1. 초기 렌더링 속도 개선

자주 사용되지 않는 복잡한 레이아웃을 ViewStub으로 대체하면, 앱 초기 실행 시 화면이 더 빠르게 로드된다.

// 에러 상황에서만 에러 화면을 inflate
if (isError) {
    val errorView = errorStub.inflate()
    // 에러 정보 표시
}

2. 메모리 사용량 감소

조건부로 보여지는 UI가 많을수록 효과가 크다. 예를 들어 프리미엄 사용자에게만 보이는 배너, 특정 상황에서만 나타나는 안내 메시지 등을 ViewStub으로 처리하면 대부분의 사용자에게는 해당 View가 메모리에 로드되지 않는다.

3. 복잡한 레이아웃 지연 로딩

상세 정보 화면처럼 스크롤해야 보이는 하단 영역이 복잡한 경우, ViewStub으로 만들어두고 사용자가 스크롤할 때 inflate하면 초기 로딩이 빨라진다.

scrollView.setOnScrollChangeListener { _, _, scrollY, _, _ ->
    if (scrollY > threshold && !isDetailInflated) {
        detailStub.inflate()
        isDetailInflated = true
    }
}

실무 활용 예시

1. 빈 화면(Empty State)

<ViewStub
    android:id="@+id/stub_empty_view"
    android:layout="@layout/empty_state"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

2. 로딩 인디케이터

<ViewStub
    android:id="@+id/stub_loading"
    android:layout="@layout/loading_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

3. 네트워크 에러 화면

<ViewStub
    android:id="@+id/stub_network_error"
    android:layout="@layout/network_error_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

ViewStub 사용 시 주의사항

  1. 한 번만 inflate 가능하다 - 다시 숨겼다가 보여줘야 한다면 ViewStub보다 visibility를 사용하는 일반 View가 낫다.
  2. inflate 후에는 ViewStub ID로 접근할 수 없다 - inflate된 실제 레이아웃의 ID로 접근해야 한다.
  3. merge 태그와 함께 사용할 수 없다 - ViewStub의 layout은 반드시 루트 요소를 가져야 한다.

언제 사용하면 좋을까?

ViewStub은 다음과 같은 상황에서 효과적이다.

  • 항상 보이지 않고 특정 조건에서만 나타나는 UI
  • 복잡하지만 자주 사용되지 않는 레이아웃
  • 사용자 액션 이후에 표시되는 UI
  • 초기 로딩 속도가 중요한 화면

반대로 자주 보였다 숨겼다 해야 하는 UI라면 ViewStub보다는 일반 View의 visibility를 조절하는 것이 더 적합하다.

마치며

View와 ViewGroup의 차이를 이해하면 안드로이드 UI가 어떻게 구성되고 동작하는지 더 명확하게 파악할 수 있다. 특히 커스텀 View나 ViewGroup을 만들 때 이런 차이를 알고 있으면 큰 도움이 된다.

여기에 ViewStub까지 적절히 활용하면 초기 로딩 속도를 개선하고 메모리 사용량을 줄일 수 있다. ViewStub은 작은 최적화처럼 보이지만, 사용자 경험을 개선하는 데 확실히 도움이 된다. 특히 앱 초기 실행 속도가 중요한 경우라면 적극적으로 활용해볼 만하다.

안드로이드 UI 개발은 이런 기본 개념들을 탄탄히 이해하는 것에서 시작된다. 오늘 정리한 내용이 더 나은 UI를 만드는 데 도움이 되길 바란다.

profile
데브누누

0개의 댓글