
Fragment란 FragmentActivity 내의 어떤 동작 또는 사용자 인터페이스의 일부를 나타낸다.
Fragment 또한 Activity와 같이 Layout 파일로부터 인플레이트 되는 뷰를 가지고 고유한 생명주기를 가지는 UI 컨트롤러이다.
둘 다 Fragment를 추가할 수 있다. 그러나 FragmentContainer를 사용하는 것을 권장한다. FrameLayout을 사용하는 경우 중복되어 사용될 때 animation에서 문제가 발생할 수도 있고, 생명주기 관련되어 문제가 발생할 수도 있다.
따라서 FragmentContainer 사용을 권장한다.
class HomeFragment: Fragment() {
private var _binding: FragmentHomeBinding? = null
private val binding: FragmentHomeBinding
get() = requireNotNull(_binding) { "앗 ! _binding이 null이다 !" }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// 대부분의 로직은 이곳에 구현
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
onDestroyView() 이후 View 객체는 Destroy되어 Java의 가비지 컬렉터에 의해 수집되어야 한다. 그러나 Fragment 객체의 경우 Activity와 다르게 여전히 활성화되어있기 때문에 객체 내의 멤버변수 binding이 있는 경우 메모리가 여전히 존재하게 된다.
따라서 ViewBinding 객체를 null로 설정하여 메모리 누수를 방지해야한다.
개발에서의 Transaction은 데이터 추가, 수정, 삭제를 의미한다.
실행을 하고 보여지는 Fragment를 설정하고 싶을 때 이걸 활용하여 설정
프래그먼트를 관리하는 다양한 메서드를 가지고 있다.
소프트웨어 공학의 소프트웨어 디자인에서 특정 컨텍스트에서 공통적으로 발생하는 문제에 대해 재사용 가능한 해결책
소프트웨어 공학에서 문제 상황을 분석하여 어떤 상황인지 파악하고, 상황에 맞는 재사용 해결책을 파악하여 이후 상황에서도 이 방식을 재사용하여 해결하는 방식
한 클래스의 인터페이스를 클라이언트에서 사용하고자 하는 다른 인터페이스로 변환하는 패턴이다. 이 패턴을 사용하면 호환성 없는 인터페이스 때문에 함께 동작할 수 없는 클래스들이 함께 작동할 수 있다.
어댑터 패턴은 호환성이 없는 두 개의 인터페이스 사이에서 작업을 처리할 수 있게 한다.
RecyclerView란 사용자가 관리하는 수많은 데이터를 개별 아이템 단위로 구분하여 화면에 출력하는 ViewGroup이며, 한 화면에 표시되기 힘든 많은 양의 데이터를 스크롤 가능한 리스트로 표시해주는 것이다.
주로 RecyclerView.Adapter 와 RecyclerView.ViewHolder 를 직접 작성한다.
class DogAdapter(context: Context) : RecyclerView.Adapter<DogAdapter.DogViewHolder>() {
private val inflater by lazy { LayoutInflater.from(context) }
private var dogList: List<Dog> = emptyList()
class DogViewHolder(private val binding: ItemDogBinding) :
RecyclerView.ViewHolder(binding.root) {
fun onBind(dog: Dog) {
binding.ivDogImage.setImageDrawable(binding.root.context.getDrawable(dog.image))
binding.tvDogName.text = dog.name
binding.tvDogSize.text = dog.size
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DogViewHolder {
val binding = ItemDogBinding.inflate(inflater, parent, false)
return DogViewHolder(binding)
}
override fun getItemCount() = dogList.size
override fun onBindViewHolder(holder: DogViewHolder, position: Int) {
holder.onBind(dogList[position])
}
fun setDogList(dogList: List<Dog>) {
this.dogList = dogList.toList()
notifyDataSetChanged()
}
}
여기서 ViewModel은 MVVM의 ViewModel과는 다르다
AAC의 ViewModel
AAC의 ViewModel은 안드로이드 아키텍처 컴포넌트(Android Architecture Component, AAC) 중 하나로, 액티비티 또는 프래그먼트와 같은 UI 컴포넌트에서 사용되는 데이터와 UI 관련 로직을 분리하여 관리하기 위한 클래스이다.
AAC ViewModel은 생명주기를 인식하고, UI와 관련된 데이터를 저장하고 관리하며, Activity 혹은 Fragment와 같은 UI 컴포넌트의 재생성이나 구성 변경과 같은 상황에서도 데이터를 유지할 수 있다.
MVVM의 ViewModel
MVVM의 ViewModel은 Model과 View 사이에서 브릿지 역할을 하는 아키텍처 구조의 일부이다. MVVM 패턴에서는 ViewModel이 Model로 부터 필요한 데이터를 가져와서 가공 후 View에 표시할 수 있는 형태로 변환하여 저장한다. 또한 ViewModel은 View의 이벤트를 수신하고, 필요한 경우 Model에 데이터 변경을 요청하고, View에 필요한 데이터를 전달한다.