80

Ran into a mysterious problem when trying to make a @BindingConversion for int to string.
The following code works for floats to strings:

xml:

...
<variable
        name="myViewModel"
        type="... .SomeModel" />
...
<TextView
            style="@style/StyleStuff"
            android:text="@{myViewModel.number}" />

code:

public class SomeModel {
    public ObservableFloat number = new ObservableFloat();
}

and setting:

viewModel.number.set(3.14f);

But if I try the same thing for ints to strings I get a crash.

 public ObservableInt number = new ObservableInt();

with

viewModel.number.set(42);

I get the following:

FATAL EXCEPTION: main
Process: ...myapplication, PID: 14311
android.content.res.Resources$NotFoundException: String resource ID #0xfa0
    at android.content.res.Resources.getText(Resources.java:1123)
    at android.support.v7.widget.ResourcesWrapper.getText(ResourcesWrapper.java:52)
    at android.widget.TextView.setText(TextView.java:4816)
    at ...executeBindings(ActivityAdaptersBinding.java:336)
    at android.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:355)

Any ideas? Thanks!

Dave
  • 1,896
  • 2
  • 14
  • 15

6 Answers6

238

android:text with an int assumes that the int is a string resource ID. Use android:text="@{Integer.toString(myViewModel.number)}".

You will also need to import the Integer class: (no longer needed)

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 1
    Aha! Thank you! I would've thought data binding would check and convert the int before it hit the text view, but apparently not~ This means that we should be careful whenever using BindingConversion if the original type might be misinterpreted and used without hitting the converter. – Dave Jun 17 '16 at 01:20
  • @Dave: "I would've thought data binding would check and convert the int before it hit the text view" -- no, because for all data binding knows, you *are* giving it a string resource ID. "This means that we should be careful" -- yes. :-) – CommonsWare Jun 17 '16 at 11:34
  • 5
    How would you do this if you wanted to create 2-way binding? – InfernalRapture Aug 08 '16 at 02:17
  • 1
    @InfernalRapture: Perhaps an `@InverseBindingAdapter`, though I haven't played with that yet. – CommonsWare Aug 08 '16 at 10:56
  • @CommonsWare That was what I was looking for, after a few hours of messing around that was the trick of it. – InfernalRapture Aug 08 '16 at 17:48
  • It matters that the import is before anything else, like in my case were i had a variable in my data clause. Import types must be before the variable. – ZooMagic Aug 02 '18 at 15:10
  • I dont think import is necessary. As java.lang.* are available by default – Irshad Kumail Jul 20 '19 at 19:50
  • how its possible two way bindings? – Sreejesh K Nair Mar 25 '20 at 06:00
  • @SreejeshKNair: `TextView` does not support input, so there is no need for a two-way binding with `TextView`. – CommonsWare Mar 25 '20 at 11:46
28

Beware, In latest DataBinding (2019), It does NOT require importing Integer nor String or you will get this error:

****/ data binding error ****msg:Missing import expression although it is registered file

official doc says : java.lang.* is imported automatically.

Just go either

android:text="@{Integer.toString(myViewModel.number)}" or

android:text="@{String.valueOf(myViewModel.number)}"

directly.

Wesely
  • 1,425
  • 14
  • 23
  • This is should be upvoted, today databinding doesn't need to import `java.lang.String` or `java.lang.Integer` in order to do the conversion. – Rhony May 25 '19 at 07:34
23

Convert int to string for set in TextView like below:

android:text="@{String.valueOf(myViewModel.number)}"

Also, String class must be imported by the layout:

<layout>
   <data>
      <import type="java.lang.String" />
   </data>

   …

</layout>
Raja Jawahar
  • 6,742
  • 9
  • 45
  • 56
19

Simplest solution, may be it would help someone.

android:text="@{`` + model.intValue}"

This can be used in two-way binding for EditText also. Where users input is set as Integer value in model, and shown as String.

android:text="@={`` + model.intValue}"

See this answer also.

Community
  • 1
  • 1
Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
6

This worked for me

  <TextView
        android:id="@+id/number"
        android:text='@={Converter.convertIntToString(myViewModel.number)}'

        />

Converter class with inverse method

public class Converter {


public static int convertStringToInt(String text) {
   return Integer.parseInt(text);
}

@InverseMethod(value="convertStringToInt")
public static String convertIntToString(int value) {
    return Integer.toString(value);
}}
shahana kareen
  • 364
  • 4
  • 10
6

It's too late but i update it for newbies. You can parse to int in xml by using:

Integer.parseInt(string)

or to String by:

String.valueOf(string)
Hosein Haqiqian
  • 579
  • 9
  • 16