Я пытаюсь реализовать некоторые пользовательские адаптеры привязки, чтобы я мог привязать значение моей модели представления к значению switch.ischecked в моем пользовательском представлении. Я хочу, чтобы состояние переключателя изменилось, если оно включено в моих изменениях модели просмотра и наоборот. Я просмотрел множество статей о том, как это сделать, но все равно ничего не делает. Я вижу, что мой метод setSwitchChecked используется реализацией привязки данных, но на самом деле он ничего не устанавливает. остальные 2 адаптера остаются неиспользованными. Любая помощь, как и то, что я упускаю или делаю неправильно, приветствуется.
ViewModel
open class SettingsViewModel @Inject constructor(): ViewModel() {
var enabled: MutableLiveData<Boolean> = MutableLiveData()
}
Фрагмент
class SettingsFragment @Inject constructor(): Fragment() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private lateinit var viewDataBinding: FragmentSettingsBinding
private lateinit var viewModel: SettingsViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view: View = inflater.inflate(R.layout.fragment_settings, container, false)
viewModel = ViewModelProviders.of(activity!!, viewModelFactory).get(SettingsViewModel::class.java)
viewDataBinding = FragmentSettingsBinding.inflate(inflater, container, false).apply {
viewmodel = viewModel
}
return view
}
}
Привязка CustomView xml
<com.stinson.sleepcycles.views.SwitchRow
android:id="@+id/switch_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:switchLabel="@string/enabled"
app:switchChecked="@{viewmodel.enabled}"/>
Пользовательский класс представления
class SwitchRow constructor(context: Context, attrs: AttributeSet, defStyle: Int = 0) :
RelativeLayout(context, attrs, defStyle), View.OnClickListener {
constructor(context: Context, attrs: AttributeSet): this(context, attrs, 0)
init {
val view = inflate(context, R.layout.view_switch_row, this)
val a = context.theme.obtainStyledAttributes(attrs, R.styleable.SwitchRow, defStyle, 0)
try {
view.text_label.text = a.getString(R.styleable.SwitchRow_switchLabel)
view.switch_toggle.isChecked = a.getBoolean(R.styleable.SwitchRow_switchChecked, false)
} finally {
a.recycle()
}
view.setOnClickListener {
view.switch_toggle.callOnClick()
}
view.switch_toggle.setOnClickListener {
toggleSwitch(view)
}
}
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
if (event.action == MotionEvent.ACTION_UP) {
this.callOnClick()
}
return super.dispatchTouchEvent(event)
}
override fun onClick(view: View?) {
if (view != null) view.callOnClick()
}
private fun toggleSwitch(view: View) {
view.switch_toggle.isChecked = !view.switch_toggle.isChecked
}
}
XML пользовательского представления
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:padding="16dp">
<TextView
android:id="@+id/text_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/text_size_medium"
tools:text="Label" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/switch_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"/>
</RelativeLayout>
Адаптеры для привязки
@BindingAdapter("switchCheckedAttrChanged")
fun setListener(switchRow: SwitchRow, listener: InverseBindingListener) {
switchRow.switch_toggle.setOnCheckedChangeListener { _, _ ->
listener.onChange()
}
}
@BindingAdapter("switchChecked")
fun setSwitchChecked(switchRow: SwitchRow, value: Boolean) {
if (value != switchRow.switch_toggle.isChecked) {
switchRow.switch_toggle.isChecked = value
}
}
@InverseBindingAdapter(attribute = "switchChecked")
fun getSwitchChecked(switchRow: SwitchRow): Boolean {
return switchRow.switch_toggle.isChecked
}