[개념] View Lifecycle

쓰리원·2022년 5월 11일
0

Lifecycle

목록 보기
2/4
post-thumbnail

1. View 란?

View는 안드로이드의 UI 를 구성하기 위해 사용됩니다. XML 상으로 구성했던 거의 모든 UI의 조상 객체가 View 입니다. 아래의 그림을 보면 View 클래스는 사용자 인터페이스 기본적인 구성 요소를 가지고 있습니다.

위 그림을 보면, View는 Button, TextView, ImageView 등의 위젯을 작성하는 데 사용되는 기본 클래스 입니다. 즉, 화면에서 그리기 및 이벤트 처리 같은 작업이 View를 통해 이루어진다고 볼 수 있습니다. View의 또 다른 서브클래스인 ViewGroup은 보이지는 않는 컨테이너로써 다른 View(또는 다른 ViewGroup)들을 포함 할 수 있습니다.

즉, 위젯을 만들기 위해서는 View를 상속해서 구현하게 됩니다. 그리고 위젯들을 담는 Layout도 View를 상속받는 ViewGroup을 상속받아 구현하게 됩니다.

2. View는 어떻게 그려지는가?

사용자와 포그라운드에서 시각적으로 상호작용을 하는 4대 컴포넌트 중 Activity가 있습니다. Activity는 focus를 받으면 운영체제에게 View 계층의 루트 노드를 제공하여 layout을 그리게 됩니다. 이를 위해 onCreate()에서 setContentView()를 통해 루트 노드를 전달합니다.

layout이 그려지는 과정은 2단계로, 각각 measure와 layout 단계입니다. layout은 루트노드부터 그리며, layout tree를 따라 부모가 먼저 그려지고 그 다음 자식들 순서대로 dfs 방식으로 그려 집니다. 부모 view(ViewGroup)는 자식 view들의 draw()를 호출하여 view 그리기를 요청합니다. 그러면 각각의 view들이 그려지게 됩니다.

1. Measure 단계

  • measure() 메서드 호출.
  • 모든 뷰들은 각각 자신의 크기(너비와 높이)를 저장.
  • 뷰의 measure()가 반환되면, getMeasuredWidth() 및 getMeasuredHeight() 값을 자식 뷰들의 값과 함께 설정.
  • 부모 뷰는 자식들에게 두 번 이상의 measure()를 호출할 수도 있음
    (자식 뷰들의 크기 합이 너무 크거나, 너무 작을 때와 같은 상황)

이러한 측정 단계에서는 아래와 같은 두 클래스를 사용 합니다.

1. ViewGrop.LayoutParams

자식view가 부모view에게 본인이 어떻게 측정되고 싶은지를 알릴 때 사용합니다.

정확한 숫자 android:layout_width="40dp"
MATCH_PARENT android:layout_width="match_parent"
WRAP_CONTENT android:layout_width="wrap_content"

2. ViewGroup.MeasureSpecs

부모view가 자식view의 크기 제한을 위해 사용합니다.

UNSPECIFIED: 제한 없음. (자식view의 measure()호출)
EXACTLY: 자식view의 정확한 사이즈를 설정. 자식view는 해당 사이즈 내에서 후손 view들을 맞춰야 함.
AT_MOST: 자식view의 최대 사이즈를 설정.

2. Layout 단계

  • layout() 메서드 호출.
  • 부모 뷰는 Measure 단계에서 측정된 크기를 사용하여 모든 자식 뷰들의 위치를 배정함 즉, Measure 때 모아놓은 크기 수치값을 기준으로 전체적인 레이아웃을 딱 그리는 과정

3. View의 생명주기

부모 뷰가 View() 를 호출하면, 화면에 렌더링 된 View는 다음 그림과 같은 생명주기 메서드를 거쳐 화면에 그려집니다.

1. constructor()

1. View(Context context)
2. View(Context context, @Nullable AttributeSet attrs)
3. View(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
4. View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)

1. View(Context context)

코드에서 View를 동적으로 만들 때 사용하는 간단한 생성자 입니다. 여기서 매개 변수 context는 뷰가 실행될 때 현재 테마, 리소스 등을 구성하는데 사용 됩니다.

2. View(Context context, @Nullable AttributeSet attrs)

XML에서 View를 전개(Inflation) 할 때 호출되는 생성자로, XML 파일에서 지정된 속성을 제공하여 XML 파일에서 View를 구성 할 때 호출 됩니다. 이 생성자는 기본 스타일인 0을 사용하므로 컨텍스트의 테마 및 지정된 AttributeSet의 속성 값만 적용됩니다.

3. View(Context context, @Nullable AttributeSet attrs, int defStyleAttr)

XML을 통해 전개를 하고 테마 속성에서 클래스별 기본 스타일을 적용합니다. 이 View 생성자는 서브 클래스가 전개할 때 자체 기본 스타일을 사용할 수 있도록 합니다. 예를 들어, Button 클래스의 생성자는 super 클래스 생성자를 호출하고 defStyleAttr에 R.attr.buttonStyle을 제공 합니다. 이를 통해 테마의 버튼 스타일은 모든 기본 View 속성 (특히 배경)과 Button 클래스의 속성을 수정할 수 있습니다.

defStyleAttr 매개 변수는 View의 기본값을 제공하는 Style 리소스 대한 참조를 포함하는 현재 테마의 속성 입니다. 기본값을 찾지 않으려면 0으로 지정할 수 있습니다.

4. View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)

XML을 전개하고 테마 속성 또는 Style 리소스에서 클래스 별 기본 스타일을 적용 합니다. 이 생성자는 서브 클래스가 전개할 때 자체 기본 스타일을 사용할 수 있도록 합니다.

매개변수 defStyleRes는 View의 defStyleAttr가 0이거나 테마에서 찾을 수 없는 경우에만 기본값을 제공하는 Style 리소스 ID 입니다. 기본값을 찾지 않으려면 0 으로 지정 합니다.

2. onAttachedToWindow()

View가 Window에 연결되면 호출 됩니다. View가 활성화 될 수 있고, 드로잉 할 표면이 있음을 알고있는 단계이고, 따라서 리소스 할당을 시작하거나 리스너를 설정할 수 있습니다.

3. onDetachedFromWindow()

View가 Window에서 분리 될 때 호출됩니다. 이 시점에서 더 이상 드로잉을 할 표면이 없습니다. 예약 된 자원을 정리하거나 정리하는 모든 종류의 작업을 중지해야하는 곳 입니다. 이 메서드는 ViewGroup에서 View제거를 호출하거나 액티비티가 Destroyed 될 때 호출됩니다.

4. onFinishInflate()

이 메서드는 View가 전개가 끝날 때 호출됩니다. 레이아웃의 경우 모든 Child View가 추가 된 후에 호출됩니다.

4. reference

https://developer.android.com/guide/topics/ui/how-android-draws
https://developer.android.com/reference/android/view/View.html
https://developer.android.com/reference/android/view/View#public-constructors
https://proandroiddev.com/the-life-cycle-of-a-view-in-android-6a2c4665b95e

profile
가장 아름다운 정답은 서로의 협업안에 있다.

0개의 댓글