Home > Software design >  Custom View with data binding -> Cannot find setter
Custom View with data binding -> Cannot find setter

Time:03-08

I need a custom layout for my toolbar on all screens so I created a custom view class that extends AppBarLayout. Its xml contains a LinearLayout with a Toolbar and a TextView. I then created a custom attribute to set the title of the toolbar in xml. It looks like this

class MyAppBarLayoutCustomView (...) : AppBarLayout(...) {
    init {
        val typedArray = context.obtainStyledAttribute(attrs, R.stylable.myAppBarLayoutCustomView, defStyle, 0)
        binding.myToolBar.title = typedArray.getString(R.stylable.myAppBarLayoutCustomView_customToolbarTitle) ?: ""
        typedArray.recylce()
    }
}

This works fine if I just set a title via xml in a fragment or activity like this

<MyAppBarLayoutCustomView
    android:id="@ id/my_app_bar_layout_view"
    andorid:layout_width="match_parent"
    andorid:layout_height="wrap_content"
    app:customToolbarTitle="@string/mainscreen_title"/>

What I want and what does NOT work is to set a title via binding like this

    <data>
        <variable
            name="viewModel"
            type="com.my.cool.app.MainScreenViewModel/>

    </data>

    <LinearLayout ...>

        <MyAppBarLayoutCustomView
            android:id="@ id/my_app_bar_layout_view"
            andorid:layout_width="match_parent"
            andorid:layout_height="wrap_content"
            app:customToolbarTitle="@{viewModel.title}"/>

    </LinearLayout>
</layout>

The binding in the viewModel looks like this

private val _title = NonNullMutableLiveData(R.string.default_title)
val title: NonNullLiveData<Int> = _title
...
_title.postValue(R.string.custom_title)

The error I get is the following

Cannot find a setter for <MyAppBarLayoutCustomView app:customToolbarTitle> that accepts parameter type 'com...livedata.NonNullLiveData<java.lang.Integer>

If a binding adapter provides the setter, check that the adapter is annotated correctly and that the parameter type matches.

CodePudding user response:

You have to use BindingAdapter in your customview class

@BindingAdapter("app:customToolbarTitle")
fun setCustomToolbarTitle(view: MyAppBarLayoutCustomView, text: Int) {
    // call the method in customview which sets the string value for title view
    view.methodnameForsettingTitle(text)
    
}

CodePudding user response:

You need to create a binding adapter with @BindingAdapter annotation to specify the attribute name (customToolbarTitle in your case) to be used.

Add this:

@BindingAdapter("customToolbarTitle")
fun setCustomToolbarTitle(textView: TextView, title: String) {
    textView.text = title
}
  • Related