2021.04.20 - [Android/AAC, MVVM] - [Android] 안드로이드 DataBinding 사용하기
[Android] 안드로이드 DataBinding 사용하기
※ DataBinding 이란? 데이터와 뷰를 연결하는 작업을 레이아웃에서 처리 할 수 있게 해주는 라이브러리 findViewById (R.id.sample_text).apply { text = viewModel.userName } 예를들어, textView에 뷰모델에서..
hanyeop.tistory.com
데이터바인딩, 뷰바인딩을 사용하려면
액티비티, 프래그먼트마다 바인딩 코드를 작성해야한다.
이것은 매우 직관적이긴 하나 새로운 액티비티, 프래그먼트 생성시마다 반복해야 하므로 효율적이지 못하다.
따라서 BaseActivity, BaseFragment 를 통해 보일러 플레이트 코드(반복되는 코드)를 정리하여 쉽게 사용해보자.
1️⃣ Activity
기존방식
class MainActivity : AppCompatActivity() {
private lateinit var binding : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this,R.layout.activity_main)
binding.lifecycleOwner = this
}
}
Activity의 경우 바인딩 생성 작업과 생명주기를 관찰할 수 있도록 전달해주는 코드가 필요하다.
BaseActivity
abstract class BaseActivity<T : ViewDataBinding>(
@LayoutRes val layoutResId: Int
) : AppCompatActivity(){
protected lateinit var binding: T
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, layoutResId)
binding.lifecycleOwner = this
init()
}
protected abstract fun init()
}
AppCompatActivity를 상속받는 추상클래스 BaseActivity 를 정의해주고,
제네릭을 활용하여 타입을 일반화한 코드를 작성해준다.
class MainActivity : BaseActivity<ActivityMainBinding>(R.layout.activity_main) {
override fun init() {
}
}
이제 BaseActivity 를 상속받아 액티비티에 맞게 구체화해주면
반복되는 코드를 줄일 수 있다.
2️⃣ Fragment
기존방식
class MainFragment : Fragment() {
private var _binding: FragmentMainBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.lifecycleOwner = viewLifecycleOwner
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
이제 프래그먼트의 경우를 살펴보면, fragment는 view보다 오래 지속되기 때문에
메모리 누수 방지를 위해 onDestroyView에서 생명주기를 관리해주어야 하므로 중복되는 코드가 더 많다.
또한, 프래그먼트는 onDestroy가 호출되지 않은 상태에서 onCreateView가 여러번 호출될 수도 있기 때문에 lifecycleOwner 도 viewLifecycleOwner로 설정해주어 생명주기를 관리해야한다. (수정)
BaseFragment
abstract class BaseFragment<T: ViewDataBinding>(
@LayoutRes val layoutResId: Int
) : Fragment(){
private var _binding: T? = null
protected val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = DataBindingUtil.inflate(inflater, layoutResId, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.lifecycleOwner = viewLifecycleOwner
init()
}
protected abstract fun init()
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
액티비티와 동일하게 추상클래스 BaseFragment 를 정의해주고,
타입을 일반화해준다.
class MainFragment : BaseFragment<FragmentMainBinding>(R.layout.fragment_main) {
override fun init() {
}
}
BaseFragment 를 상속받아 구체화한다.
전체 코드는 이곳에서 확인할 수 있습니다.
https://github.com/HanYeop/AndroidStudio-Practice2/tree/master/BaseEx
GitHub - HanYeop/AndroidStudio-Practice2: (2021.05.20~) 안드로이드 학습 내용 저장소
(2021.05.20~) 안드로이드 학습 내용 저장소. Contribute to HanYeop/AndroidStudio-Practice2 development by creating an account on GitHub.
github.com
참고
https://gift123.tistory.com/57