DataBinding – Two-way(양방향) Databinding with Custom View
2021. 3. 4. 21:06ㆍ모바일/Android_Kotlin
DataBinding – Two-way(양방향) Databinding with Custom View
CustomView가 아닌 일반적인 방법
android:text="@={viewModel.mContent}
CustomView
- CustomView에 양방향 데이터 바인딩을 적용하려면 꽤 복잡하다.
- customview에 적절한 변수값 선언하기
<my.timer.custom.KeyboardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textSize="20sp"
app:content="@={dashboardViewModel.content}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@+id/ll_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
- CustomView 클래스에 Databinding 연결하기
constructor(
context: Context,
attrs: AttributeSet?,
defStyleAttr: Int
) : super(context, attrs, defStyleAttr) {
initView()
}
/**
* init View Here
*/
private fun initView() {
//*study*
//아래 주석은 데이타 바인딩 사용 안할 때
// val rootView = (context
// .getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater)
// .inflate(R.layout.keyboard, this, true)
val inflater = LayoutInflater.from(context)
mBinding = DataBindingUtil.inflate(inflater,R.layout.keyboard,this,
true)
mBinding.view = this
- BindingAdapter 구현하기
@BindingAdapter("content")
@BindingAdapter("contentAttrChanged")
@BindingAdapter listener 에 들어갈 이름은 위에서 만든 메서드에 사용되었던 @BindingAdapter 의 이름에 AttrChanged 를 붙인 이름
내부에서는 TextWatcher 를 새로 생성하고, EditText 에 설정하는 작업을 한다. 그리고 TextWatcher 의 afterTextChanged 옵션에서 listener.onChange 를 호출해준다. 이렇게 되면, EditText 의 afterTextChanged, 즉 텍스트가 변경 완료되었을 때 자동으로ViewModel 에 설정될 것이다.
@InverseBindingAdapter(attribute = "content",event = "contentAttrChanged")
object KeyboardViewReverseBinding {
//*study*
//BindingAdapter는 데이터가 변경되었을 때 수행하고 싶은 작업을 작성
@BindingAdapter("content")
@JvmStatic
fun setKeyboardViewContent(view: KeyboardView, content: String?) {
val old = view.password_field.text.toString()
if (old != content) {
view.password_field.setText(content)
}
}
@JvmStatic
@BindingAdapter("contentAttrChanged")
fun setKeyboardViewInverseBindingListener(view: KeyboardView, listener: InverseBindingListener?) {
val watcher = object : TextWatcher {
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
}
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
}
override fun afterTextChanged(editable: Editable) {
listener?.onChange()
}
}
view.password_field.addTextChangedListener(watcher)
}
//*study*
//InverseBindingAdpater 메서드는 역으로 레이아웃의 사용자 정의 속성값이 변경되었을 때 뷰 모델 등과 같은
//레이아웃 변수에 변경 사항을 전달하여 양방향 바인딩이 구현될 수 있게 한다.
@InverseBindingAdapter(attribute = "content",event = "contentAttrChanged")
@JvmStatic
fun getContent(view: KeyboardView): String {
return view.password_field.text.toString()
}
}
참고
https://pyxispub.uzuki.live/?p=917#XML_Code
https://medium.com/@douglas.iacovelli/custom-two-way-databinding-made-easy-f8b17a4507d2
'모바일 > Android_Kotlin' 카테고리의 다른 글
LiveData - Transformations.map, switchMap (0) | 2021.06.03 |
---|---|
AndroidManifest.xml receiver tag is incompatible with attribute description (attr) reference. (0) | 2021.03.08 |
take (0) | 2020.12.17 |
[Kotlin] Sequence (0) | 2020.12.17 |
[kotlin] filter, map, all, any, count, find, groupBy, flatMap 함수 정리 (0) | 2020.12.17 |