Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- constraint
- compose
- 프리코스
- 컴포즈
- broadcast reciver
- activity
- 안드로이드
- android studio
- 로또 미션
- Android
- moshi
- 최상단
- EditText Button
- 안드로이드 키보드
- onscrollstatechanged
- 멀티모듈
- 우아한테크코스
- serialization
- recyclerview
- GSON
- coil
- 우테코 6기
- 이미지 로딩
- buildSrc
- layoutinflater
- 안드로이드 스튜디오
- Glide
- 우테코
- 4대 컴포넌트
- 코틀린
Archives
- Today
- Total
정답보다 해답을
[Android] LayoutInflater, 알고 쓰자 - 생명주기와 View 생성 관리 본문
목차 📑
- LayoutInflater란 무엇인가
- 동작 방식과 기본 개념
- 생명주기에 따른 Inflate 패턴
- RecyclerView의 View 재활용과 Inflate
- inflate() 메서드와 파라미터 이해
- ViewBinding과 함께 사용하기
- 안티패턴과 주의사항
- 주요 사용 팁
1. LayoutInflater란 무엇인가 💡
LayoutInflater는 XML 레이아웃 파일을 실제 View 객체로 변환하는 안드로이드의 시스템 서비스입니다.
// XML 레이아웃
<LinearLayout>
<TextView android:id="@+id/title"/>
</LinearLayout>
// View 객체로 변환
val view = layoutInflater.inflate(R.layout.my_layout, container, false)
2. 동작 방식과 기본 개념 ⚙️
2.1 기본 동작 과정
- XML 파싱
- View 객체 생성
- 속성 적용
- 부모에 추가 (attachToRoot 값에 따라)
2.2 LayoutInflater 얻기
// Activity에서
val inflater = layoutInflater
// Context에서
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
// 정적 메서드로
val inflater = LayoutInflater.from(context)
3. 생명주기에 따른 Inflate 패턴 🎯
3.1 Activity의 생명주기와 Inflate
class MainActivity : AppCompatActivity() {
private val binding by lazy {
ActivityMainBinding.inflate(layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
// View 사용 가능
}
}
Activity 특징:
- onCreate에서 한 번만 inflate
- Activity 종료 시 자동 정리
- Context 직접 사용 가능
- Window에 직접 설정
3.2 Fragment의 생명주기와 Inflate
class MyFragment : Fragment() {
private var _binding: FragmentBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null // 메모리 정리 필수
}
}
Fragment 특징:
- onCreateView에서 매번 새로 inflate
- onDestroyView에서 명시적 정리
- Configuration changes 대응
- View 재생성 가능성
4. RecyclerView의 View 재활용과 Inflate 📋
4.1 View 재활용 매커니즘
class MyAdapter : RecyclerView.Adapter<MyAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
ItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
// View 재사용
}
}
RecyclerView 특징:
- View 필요시에만 inflate
- View 재활용으로 메모리 효율화
- parent.context로 안전한 Context 사용
5. inflate() 메서드와 파라미터 이해 📝
fun inflate(
@LayoutRes resource: Int, // 레이아웃 리소스 ID
root: ViewGroup?, // 부모 ViewGroup
attachToRoot: Boolean // 부모에 즉시 추가 여부
): View
파라미터 의미:
- resource: inflate할 레이아웃 리소스
- root: 생성될 View의 부모
- attachToRoot: 부모에 즉시 추가 여부
6. ViewBinding과 함께 사용하기 🔄
6.1 ViewBinding 설정
android {
buildFeatures {
viewBinding = true
}
}
6.2 컴포넌트별 ViewBinding
// Activity
val binding = ActivityMainBinding.inflate(layoutInflater)
// Fragment
val binding = FragmentMainBinding.inflate(inflater, container, false)
// RecyclerView
val binding = ItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
7. 안티패턴과 주의사항 ⚠️
7.1 피해야 할 패턴
// Activity Context 직접 참조
val inflater = requireActivity().layoutInflater // 위험!
/*
문제점:
Fragment의 생명주기와 Activity의 생명주기가 다름
Fragment가 detach된 상태에서 Activity가 재생성되면 크래시 발생 가능
Configuration changes(화면 회전 등) 발생 시 메모리 누수 위험
Fragment가 여러 Activity에서 재사용될 때 문제 발생
*/
// null root 사용
inflater.inflate(R.layout.item, null) // LayoutParams 미설정
/*
문제점:
XML에 정의된 레이아웃 파라미터(layout_width, layout_height 등)가 무시됨
부모 ViewGroup의 레이아웃 특성이 적용되지 않음
예상치 못한 레이아웃 동작 발생
RecyclerView나 ViewPager 등에서 크기 측정 오류 발생 가능
*/
// Fragment에서 잘못된 attachToRoot
inflater.inflate(R.layout.fragment, container, true) // 잘못된 사용
/*
문제점:
Fragment의 View가 container에 직접 추가되어 Fragment 매니저의 관리를 받지 못함
Fragment 생명주기 이벤트가 정상적으로 동작하지 않음
Fragment 트랜잭션(add, replace 등) 동작 시 문제 발생
여러 개의 Fragment가 동시에 추가되어 화면이 겹치는 문제 발생 가능
*/
7.2 올바른 사용법
// Fragment에서
override fun onCreateView(...): View {
return FragmentBinding.inflate(inflater, container, false).root
}
// RecyclerView에서
override fun onCreateViewHolder(...): ViewHolder {
return ViewHolder(
ItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
8. 주요 사용 팁 💡
- Fragment에서는 전달받은 inflater 사용하기
- RecyclerView에서는 parent.context 활용하기
- attachToRoot 값 상황에 맞게 사용하기
- ViewBinding으로 type-safe하게 접근하기
- 적절한 생명주기에서 정리하기
'Android' 카테고리의 다른 글
| [Android] Android Studio에서 SHA KEY 확인하기 (3) | 2024.12.16 |
|---|---|
| [Android] 안드로이드 Fragment Lifecycle, 알고 쓰자 (2) | 2024.11.19 |
| [Android] Google Play Console 한국어 설정 (2) | 2024.11.02 |
| [Android] Context, 알고 쓰자 (1) | 2024.10.31 |
| [Android] 리사이클러뷰에서 상단으로 스크롤하는 버튼 구현 - onScrollStateChanged (3) | 2024.10.30 |