0

Hi am tryin to use data binding to bind a drawable res ID into a textview via code but i keep getting this error:

Cannot find a getter for <android.widget.TextView android:background> that accepts parameter type 'int'

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

Here is the viewModel code

   @DrawableRes
    private var buttonBg: Int = R.drawable.white_btn

    @Bindable
    fun getButtonBg(): Int {
        return buttonBg
    }

    @Bindable
    fun setButtonBg(bgRes: Int) {
        if (buttonBg != bgRes) {
            buttonBg = bgRes
            notifyPropertyChanged(BR.buttonBg)
        }
    }

xml

 <TextView
            android:id="@+id/toggle_textButton"
            style="@style/TextAppearance.AppCompat.Body1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@={viewModel.buttonBg}"
            android:padding="5dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="@string/follow" />
P. Michta
  • 30
  • 1
  • 5
Jono
  • 17,341
  • 48
  • 135
  • 217

1 Answers1

1

Sorry I am not as familiar with Kotlin, but I know in Java that you can setup a static data binding to ensure it will use resources:

    @BindingAdapter("android:background")
    public static void setBackground(TextView view, Integer buttonBackground){
        Drawable background = view.getContext().getResources().getDrawable(buttonBackground, null);
        view.setBackground(background);
    }

You can then keep the binding as you have it in your layout xml.

Edit: More information can be found at https://developer.android.com/topic/libraries/data-binding/binding-adapters.html#kotlin

JacquesBauer
  • 226
  • 2
  • 7
  • But if i call setBacground from outside the viewModel to dyanmically change the bg, i would have to pass a textview? – Jono Nov 27 '19 at 11:09
  • You do not have to call this static method. The databinding library will call the method with the appropriate TextView and the data defined when you set it up in the xml layout file (the ```android:background="@={viewModel.buttonBg}"``` part). Also any changes to the Integer buttonBackground from your binding will call the setBackground binding method with the appropriate TextView. – JacquesBauer Nov 27 '19 at 14:15
  • So how can i dynamically change the background from code then? This is why i want to use data binding, so i can initially set a background and then later during the lifecycle of the view, change the background based on a state i have changed. this works perfectly fine for changing the text but not so for background drawable as i keep getting compilation errors saying how it cant find a setter or getter for a drawable(android:background) – Jono Nov 27 '19 at 14:32
  • If you want to change the background dynamically, all you would have to do is call your setButtonBg method with whatever you want. The databinding library will go ahead and change the background then. From some further research I came across the same error as you and found that if you have not already you should define: ```apply plugin: 'kotlin-kapt'``` in your build.gradle. (referencing https://stackoverflow.com/questions/52655607/why-is-this-bindingadapter-not-working-in-kotlin ) – JacquesBauer Nov 27 '19 at 15:38
  • ahh ok so the setBackground method is a new method i create but i dont indirectly use as android databinding will use that? How does android databinding know to use that method? – Jono Nov 27 '19 at 15:57
  • 1
    Correct and the combination of the string inside of the @BindingAdapter annotation and the first parameter of the binding adapter method seem to tell android when to override the default behavior. So with the example I have in the answer it would use the setBackground method when using databinding with android:background on a TextView in your xml layout. – JacquesBauer Nov 27 '19 at 16:35
  • 1
    Another note, you can actually define whatever string you would like for the BindingAdapter and it can pick it up in the xml layout. So if you define a function such as: ```@BindingAdapter("backgroundSetter")``` and then refer to it in the xml layout as ```app:backgroundSetter="@{viewModel.buttonBg}"``` – JacquesBauer Nov 27 '19 at 16:41
  • Brilliant this worked a treat. Data binding is no easy subject! – Jono Nov 27 '19 at 17:17
  • Glad to hear it helped! – JacquesBauer Nov 27 '19 at 17:24