Decor View

GDSC Android·2024년 3월 28일

Android에서 화면을 그리는 방법

  1. XML에 정의된 Root Layout과 Child View들의 속성을 읽어서 실제로 View를 만듦 => inflate
    이 Inflate는 setContentView() 메서드를 통해 실행이 됨
  2. setContentView()를 통해 객체가 만들어지면 이 layout들은 Surface와 Window에 의해 사용자의 눈에 보이게 됨

Window마다 각각 Surface를 갖는데, 이 Surface에 view들을 Canvas에 그리는 방식


Window

  • 최상위 계층 Window를 위한 추상기본 클래스
  • 이 클래스의 instance는 window manager에게 추가되는 top-leve view로 사용되어야 함
  • 백그라운드, 제목 영역, 기본 키 처리 등의 표준 UI 정책을 제공
  • View는 UI를 구성하는 최소단위이고, Window는 UI를 구성하는 최대단위
  • Android 전체 화면부터 Android UI를 보여줄 수 있는 대표적인 개체들인 Activity, Dialog, Toast 등은 모두 각자의 개별적인 Window를 가지고 있음
//setContentView()함수들
public abstract void setContentView (View view, 
                ViewGroup.LayoutParams params)
                
public abstract void setContentView (View view)


public abstract void setContentView (int layoutResID)

화면 내용을 명시적 view로 설정합니다. 이 view는 화면의 view 계층 구조에 직접 배치됩니다.




DecorView 란?

Activity 의 제일 상단 뷰 (root 뷰)로 윈도우의 배경을 유지하고 있음.

Activity 에서 setContentView로 화면을 연결할 때, 안드로이드는 Activity Window에 Activity 뷰를 add



DecorView는 PhoneWindow의 inner 클래스이며 Activity에 대한 View 계층의 root container로, FrameLayout을 extend한 것.

  • Window는 사실 Interface이며 구현 클래스인 PhoneWindow를 활용하여 View가 Window에 배치.
  • 그리고 PhoneWindow는 Root View인 DecorView를 생성.
  • 설정된 Window는 속성 값에 따라 DecorView에 기본으로 설정 될 layout resouce를 선정하고, 해당 layout 안에서 id 속성으로 android:id/content 값을 갖는 ViewGroup을 찾아서 해당 ViewGroup을 parent view로 설정.
  • 그 parent view가 FrameLayout이고 이 안에 setContentView()에 설정한 XML이 배치


이 계층 구조는 "Decor"(즉, 윈도우 제목)를 모두 포함하며, 내용 보기도 포함.

DecorView에서 getWindow().setBackgroundDrawable(Drawable drawable)를 Activity에서 호출해서 window의 background를 변경 할 수 있음.

  1. ActivityManagerService는 ActivityThread를 호출하여 액티비티 런치. ActivityThread.performLaunchActivity()에서 Activity인스턴스 생성하고 activity.attach() 호출

  2. Activity는 attach()에서 PhoneWindow 객체 생성. 이 PhoneWindow는 액티비티내 뷰들의 root로서 DecorView 인스턴스 포함.
    mWindow = PolicyManager.makeNewWindow(this);

  3. ActivityManagerService는 ActivityThread를 호출하여 액티비티를 resume시킴.
    WindowManager 인스턴스가 생성되고 decorView가 WindowManager에 추가됨.
    ActivityThread.handleResumeActivity()

  4. WindowManager의 addView(decor)에서 ViewRoot 인스턴스를 생성하고 viewRoot.setView(decor) 호출

  5. viewroot.setView(decor)에서 IWindowSession을 통해 WindowManagerService에 IWindow인스턴스를 추가
    IWindowSession.add(window) 



Decor View는 언제 사용?


-> 상태 줄이 투명

activity.window.apply {
            clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
            addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
            decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            statusBarColor = Color.TRANSPARENT
        }
  • 먼저 FLAG_TRANSLUCENT_STATUS가 활성화 되어있다면, 반투명으로 나오기 때문에 이 flag를 제거
  • system bar 의 배경을 우리의 window 가 책임을 지겠다고 system에게 알려주는 것이 FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
  • decorView에서 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN으로 설정하고, statusBarColor를 투명으로 지정

참고자료

https://medium.com/@MrAndroid/android-window-basic-concepts-a11d6fcaaf3f

https://ecogeo.tistory.com/251 [아키텍트를 꿈꾸며 - 에코지오:티스토리]

https://developer.android.com/reference/android/view/WindowManager.LayoutParams [WindowManager.LayoutParams]

https://colinch4.github.io/2020-12-01/Android%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-UI%EB%A5%BC-%EA%B5%AC%EC%84%B1%ED%95%A0%EA%B9%8C(1)-Inflate/ [[안드로이드 기초] Android는 어떻게 UI를 구성할까?(1) - Inflate]

https://proandroiddev.com/android-full-screen-ui-with-transparent-status-bar-ef52f3adde63 [Android: Full Screen UI with Transparent Status Bar]

profile
건국대학교 GDSC 안드로이드 파트의 블로그입니다

0개의 댓글