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가 커지는 경우
- RecylerView의
setHasFixedSize(boolean b)
가 false로 설정된 경우 아이템이 추가되거나 제거될 때 requestLayout()
이 호출된다.