Databinding 라이브러리 사용 시, 사용되는 경우(Activity, Fragment, Adapter, CustomView...)에 따라 xml 레이아웃을 바인딩하는 방법에 차이가 있어서 간단히 정리해보았습니다.
모든 내용은, Android developers 래퍼런스의 Generated binding classes 가이드를 참고하였습니다.
Activity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView(this, layoutId)
}
Fragment, Adapter
val binding = ListItemBinding.inflate(layoutInflater, viewGroup, false)
// or
val binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)
//Fragment 예시
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding = DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false)
//or
val binding = FragmentMainBinding.inflate(inflater, container, false)
val view = binding.root
return view
}
//Adapter 예시
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
//View를 넘기는 경우
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_recyclerview, parent, false)
return ViewHolderItem(view) //뷰홀더에서 아래와 같이 binding 처리 필요
//val binding = DataBindingUtil.bind(view)
//binding을 넘기는 경우
val binding: ItemRecyclerviewBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.item_recyclerview, parent, false)
//or
val binding = DataBindingUtil.bind(view) //뷰홀더에서 처리하는 binding과 동일
return ViewHolderItem(binding)
}
CustomView
ViewGroup을 사용하는 경우, 즉 ViewGroup을 상속받는 CustomView의 경우는,
binding.inflate(layoutInflater, viewGroup, attachToRoot) 함수를 사용합니다.
class HeaderView(context: Context?, attrs: AttributeSet?, defStyleAttr: Int)
: RelativeLayout(context, attrs, defStyleAttr) {
constructor(context: Context?) : this(context, null)
constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
//view_header.xml파일명을 기반으로 자동생성된 binding 객체 ViewHeaderBinding
private val binding: ViewHeaderBinding = ViewHeaderBinding.inflate(LayoutInflater.from(context), this, false)
init {
TODO()
}
}
여기에서 중요한 점은,
binding 변수에 inflate 하는 binding 타입이, DataBindingUtil이 아니라 xml명을 기반으로 자동 생성된 ViewDataBinding 객체를 사용하여 inflate 해준다는 점과, (예제에서, view_header.xml파일명을 기반으로 자동 생성된 binding 객체 ViewHeaderBinding에 해당)
binding.inflate(layoutInflater, viewGroup, attachToRoot)의 파라미터 중
attachToRoot 파라미터를 true로 설정하면, root의 자식 View로 자동으로 추가되고 (xml파일 내에 커스텀뷰를 정의해서 사용하는 경우)
false로 하는 경우에는, addView(view) 를 사용해서 뷰를 추가하는 경우입니다.
또는, 이미 구성된(inflate) View를 따로 바인딩하는 경우에는 아래와 같이 할 수 있습니다.
val binding: ViewHeaderBinding = ViewHeaderBinding.bind(viewRoot)
Others
바인딩 클래스를 미리 알 수 없는 경우에는, DataBindingUtil 클래스를 사용하여 바인딩할 수 있습니다.
val viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent)
val binding: ViewDataBinding? = DataBindingUtil.bind(viewRoot)
'안드로이드 기술 공유' 카테고리의 다른 글
Repository Pattern 이해하기 (0) | 2020.04.06 |
---|---|
맥 OS 에서 프로젝트 빌드 속도 개선을 위한, 간단한 체크사항! 꿀팁! (0) | 2020.03.16 |
Android DataBinding vs Kotlin Extensions 의 XML 레이아웃 접근, 어떤 방식이 더 좋을까? (0) | 2020.02.23 |
기존 레이아웃을 데이터바인딩 레이아웃으로, 한방에 자동 변환하기! (0) | 2020.02.12 |
AndroidX 로 마이그레이션 하기 (0) | 2020.02.06 |