如何在自定义视图/组件中双向绑定Seekbar?

时间:2019-03-06 08:03:45

标签: android android-databinding

我正在尝试在包含SeekBar的自定义视图上使用2向数据绑定。布局非常简单,但是我需要在整个项目中重复使用它,因此将其包装到自定义视图/组件中

<androidx.constraintlayout.widget.ConstraintLayout   ... />

<TextView .../>
<TextView .../>

<SeekBar
    android:id="@+id/ds_seekbar"
    android:layout....
    android:max="9"
    android:min="0"
    android:progress="0"
   </androidx.constraintlayout.widget.ConstraintLayout>

支持代码看起来像这样(简化)

CustomView @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0

) : ConstraintLayout(context, attrs, defStyleAttr), View.OnClickListener {

    init {
        LayoutInflater.from(context).inflate(R.layout.custom_view, this, true)
        ds_description.setOnClickListener(this)

    }

    override fun onClick(view: View) {
//onClick implementation 
        }
}

我可以在ViewModel中为将要使用此自定义视图的布局进行绑定,并在那里使用具有自定义属性的BindingAdapter(例如app:seekbar),但是自定义视图将被多次使用,宁愿拥有视图所需的大量逻辑,并在ViewModel中进行“更轻松”的处理。

我读了Android 2-Way DataBinding With Custom View and Custom Attr和许多其他文章,这些文章似乎有些不同,但主题相同,但是无论我如何编写getter和setter,我总是遇到无法找到的kapt异常吸气剂/吸气剂。

我没有正确注释方法,或者它们的签名错误。

理想情况下,我想要类似的东西:

   CustomView @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0

) : ConstraintLayout(context, attrs, defStyleAttr), View.OnClickListener, SeekBar.OnProgressChangedListener {

... ds_seekbar.setOnProgressChangedListener(this)

然后在主布局中,在自定义视图上放置app:progress(如果有人可以展示它如何完成android:progress,甚至更好),以便在传递对象时进行绑定。

1 个答案:

答案 0 :(得分:0)

好吧,经过越来越多的抓挠之后,这就是我所附带的东西,似乎可行。这是正确的方法还是性能/可靠性如何-我不确定

@InverseBindingMethods(InverseBindingMethod(type = CustomView::class, attribute = "progress", event = "progressAttrChanged"))
CustomView @JvmOverloads constructor(...

private var progress = 0
private var mInverseBindingListener: InverseBindingListener? = null


cv_seekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
        override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) {
            progress = i + 1
            if (mInverseBindingListener != null) {
                mInverseBindingListener!!.onChange()
                cv_indicator.text = progress.toString()
            }
        }...
   })

fun getProgress(): Int {
    return progress
}

fun setProgress(p: Int) {
    if (progress != p) {
        progress = p
    }
}

fun setProgressAttrChanged(inverseBindingListener: InverseBindingListener?) {
    if (inverseBindingListener != null) {
        mInverseBindingListener = inverseBindingListener
    }
}

那么XML是

 <com.xxx.CustomView
                android:id="@+id/xxx"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:progress="@={viewModel.dataobject.value}"
          ....
                />