Я пытаюсь реализовать некоторые настраиваемые привязывающие адаптеры, чтобы я мог привязать данные своего значения viewmodel к значению 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
}