💡 Intro
레벨 인터뷰를 준비하기 위해 Do It 안드로이드 앱 프로그래밍 책을 꺼내보았고, 인플레이션에 대해 설명하려고 보니 부족함을 느꼈다. 최근에 정리한 글들과 비교하면 기본적인 내용이라고 생각할 수 있지만, 기본이 가장 중요하다고 생각하기 때문에 이해한대로 정리해보려고 한다.
❓Inflation
단순히 XML레이아웃 파일을 만들었다고 소스코드에서 뷰를 참조할 수 없다. 왜? 아직 메모리에 올라가있지 않으니까!
그럼 어떻게 해야할까?
인플레이션은 XML레이아웃의 내용이 메모리에 객체화되는 과정이다. 일반적으로 액티비티나 프래그먼트가 생성될 때 setContentView 메서드로 XML레이아웃을 인플레이션하고 화면에 표시한다. 이 과정에서 XML레이아웃 파일에 정의되어 있는 뷰들은 해당 액티비티나 프래그먼트의 계층 구조로 메모리에 객체로 생성된다. 이렇게 생성된 뷰들은 소스코드에서 참조가 가능해진다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_movie_list)
}
Empty Acitivty를 새로 생성하면 위처럼 onCreate 메서드가 자동으로 생성된다.
Activity는 AppCompatActivity를 상속하고 있고, AppCompatActivity에는 화면에 필요한 메서드들이 있는데 그 중 하나가setContentView다.
setContentView 메서드 중 xml레이아웃 id를 파라미터로 받는 메서드를 살펴보면 내부에서도 setContentView를 통해 xml레이아웃을 인플레이션 해주는 것을 볼 수 있다.
만약 setContentView로 XML레이아웃을 인플레이션하지 않은 채 뷰에 참조하려고 하면 에러가 발생한다. 이러한 이유는 아직 setContentView가 호출되지 않았다면 XML레이아웃이 메모리에 객체화 되지 않았다는 뜻이고, 객체화되지 않은 뷰를 참조하려고 했기 때문이다.
❓ LayoutInflater
setContentView 메서드는 액티비티의 화면 전체를 설정하는 역할만 수행하기 때문에 부분 화면을 메모리에 객체화할 수 없다. Adapter 클래스나 프래그먼트와 같은 부분 화면을 메모리에 객체화 하기 위해서는 어떻게 해야 할까?
이를 위해 안드로이드는 시스템 서비스로 LayoutInflater 클래스를 제공한다.
LayoutInflater 클래스가 가지고 있는 inflate 메서드의 파라미터로 부분 화면의 XML레이아웃과 부모 컨테이너를 전달하면 부모 컨테이너에 XML레이아웃을 설정하는 과정을 거친다. 이를 통해 레이아웃에 정의된 뷰들이 메모리에 로딩되며 객체화 과정이 진행된다.
아래는 진행한 미션에서 LayoutInflater를 사용하는 코드 중 일부다.
// HomeFragment.kt (android-movie-ticket)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
return inflater.inflate(R.layout.fragment_home, container, false)
// BaseViewHolder.kt (android-movie-ticket)
open class BaseViewHolder(
parent: ViewGroup,
layoutId: Int,
) : RecyclerView.ViewHolder(
LayoutInflater.from(parent.context).inflate(layoutId, parent, false),
)
추가로 LayoutInflater 객체는 from 메서드를 통해 참조할 수 있다.
static LayoutInflater LayoutInflater.from(Context context)
// 같은 방법
val layoutInflater1 = layoutInflater
val layoutInflater2 = LayoutInflater.from(this) // activity
val layoutInflater3 = LayoutInflater.from(requireContext()) // fragment
참고
Do it 안드로이드 앱 프로그래밍