View Lifecycle

boogi-woogi·2024년 1월 23일
0
post-thumbnail

View LifeCycle

  • View의 LifeCycle은 크게 Creation -> Measure -> Layout -> Draw -> Destruction 단계로 나뉘어진다.
  • 이 글에서 살펴볼 부분은 Measure, Layout, Draw 단계이다.
    • Creation 단계에서 뷰가 생성되고 메모리에 객체가 할당된다.
    • Destruction 단계에서는 뷰가 더 이상 필요하지 않은 경우 메모리에서 해제하고 소멸한다.

1. Measure

Measure 단계에서는 View의 크기를 계산하기 위해 호출된다. ViewGroup의 경우에는 각각의 자식 뷰에 대한 measure를 호출한다.

  • xml에서 ViewGroup의 depth가 깊어지면 자식 뷰 -> 자식 뷰 -> 자식 뷰의 크기를 재귀적으로 측정해야함으로 비용이 커질 수도 있다.
  • ConstraintLayout을 사용하면 View 계층 구조를 단순화 할 수 있기 때문에 View 계층 구조에 대한 순회비용을 줄일 수 있다.
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

MeasureSpec

View의 크기를 측정하는 과정에서 Parent View에서 Child View로 크기에 대한 제약 사항을 전달할 때 활용된다. MeasureSpec을 이용해 View의 크기를 측정하고 배치할 때 정확한 크기를 결정할 수 있다. 다음 세 가지 모드로 제약 조건을 설정할 수 있다.

  • MeasureSpec.EXACTLY: Parent View가 Child View에 대해 정확한 크기를 지정한 경우이다. Child View는 해당 크기를 갖게된다.
  • MeasureSpec.AT_MOST: Parent View가 Child View에 대해 최대 크기를 지정한 경우이다.
  • MeasureSpec.UNSPECIFIED: Parent View가 Child View에 대해 제약을 두지 않은 경우이다. Child View는 자신이 원하는 크기로 설장할 수 있다.

2. Layout

View의 크기를 측정한 후 호출되며 화면 상의 위치를 지정하는 단계이다.

protected void onLayout(boolean changed, int left, int top, int right, int bottom)

3. Draw

측정된 View의 크기와 위치를 바탕으로 View를 그린다. onDraw()는 여러 번 호출될 수 있기 때문에 무거운 작업을 하지 않아야 한다.

protected void onDraw(Canvas canvas)

invalidate() vs requestLayout()

invalidate()

  • draw 과정이 수행된다. View의 속성이나 데이터가 변경되었을 때 사용한다.
    • ex) background 변경, textView에 표시된 text가 변경

requestLayout()

  • measure -> layout -> draw 단계를 다시 거치게 된다. View의 크기나 위치, 혹은 Parent View의 크기나 레이아웃이 변경되었을 때 사용한다.
    • ex) height가 wrap_content로 설정된 recycler view의 아이템이 추가되어 height가 커지는 경우
    • RecylerViewsetHasFixedSize(boolean b)가 false로 설정된 경우 아이템이 추가되거나 제거될 때 requestLayout()이 호출된다.
profile
https://github.com/boogi-woogi

0개의 댓글