3

Just learned DataBinding and find out that the powerful built-in toString() from Kotlin is not available:

<layout 
    xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="student"
            type="com.example.databindingtest2.Student" />

    </data>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{student.name}"
        android:textColor="@android:color/black"
        android:textSize="30sp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="@{student.age.toString()}"    //doesn't work, age is integer
        android:textColor="@android:color/black"
        android:textSize="30sp" />

</layout>

I know String.valueOf() will work, but it's not Kotlin way. Any help would be appreciated.

Sam Chen
  • 7,597
  • 2
  • 40
  • 73
  • 1
    What does "not available" and "doesn't work" mean? What are your symptoms? – CommonsWare Oct 03 '20 at 14:45
  • If `age` is a int, you could write a bindingadapter and pass it in there and use `view.text = value.toString()` there – Andrew Oct 03 '20 at 15:19
  • @CommonsWare I mean when I type "." after `age`, the `toString()` function doesn't show up, so called "not available". – Sam Chen Oct 03 '20 at 15:41
  • Why not just val textView = student.age.toString() in your activity? Btw this lacks info from your code. Where are you gonna use the TextView? How? – Branddd Oct 03 '20 at 15:41
  • That is code completion in an IDE. If you type in `toString()` yourself -- as you did in the question -- and you run the code, does it work? If not, what are your symptoms? – CommonsWare Oct 03 '20 at 15:45
  • @CommonsWare it doesn't compile, shows `cannot find method toString() in class int` – Sam Chen Oct 03 '20 at 15:54
  • 2
    @Branddd that way makes `DataBinding` not meaningful. – Sam Chen Oct 03 '20 at 16:00

2 Answers2

9

doesn't work, age is integer

There is no type in either Java or Kotlin named integer. I am going to guess that age is a Kotlin Int.

cannot find method toString() in class int

Data binding is implemented in Java, not Kotlin. Java/Kotlin interoperability, combined with the data binding compiler, appears to be converting the Kotlin Int into the Java int primitive type. Java primitives do not extend Object and do not have toString().

Personally, I recommend not investing in data binding. Jetpack Compose will make data binding obsolete in a year or so.

If you still wish to use data binding, the simplest solution is String.valueOf(). While you say "it's not Kotlin way", you are working with data-binding-generated Java, not Kotlin.

If you still wish to use data binding, and you insist that you must use toString()... try @{Integer.valueOf(student.age).toString()}. Integer.valueOf() will give you a Java Integer instance boxing your int, and Integer has a toString() method. This still has nothing really to do with Kotlin, but it would let you use toString().

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Is there an alternative for data binding? Or better yet, in Jetpack Compose, what do you recommend us studying as a replacement for data binding. – Branddd Oct 10 '20 at 12:33
  • 2
    @Branddd: I recommend that you learn Kotlin. With Jetpack Compose, UIs are constructed in Kotlin, instead of through layout resource XML files. – CommonsWare Oct 10 '20 at 12:34
  • @CommonsWare Kotlin is what im actually using right now. But i learned it in Udacity, which our first lesson was actually Kotlin and DataBinding. Im actually learning this right now that data binding is Java. But still tho, calling findViewById is expensive with the performance. And if DataBinding will be obsolete like you said, then that means, that us newbies will have to learn a new way of calling elements from our UI in the activity. If not dataBinding then is there an alternative that does the same job as DataBinding? – Branddd Oct 10 '20 at 12:43
  • 2
    @Branddd: "calling findViewById is expensive with the performance" -- data binding calls `findViewById()`. `findViewById()` is unavoidable -- it is merely a question of whether you are calling it or other code that you use is calling it. – CommonsWare Oct 10 '20 at 12:48
  • 2
    @Branddd: "If not dataBinding then is there an alternative that does the same job as DataBinding?" -- for `View`-based Android development in Kotlin, other modern approaches are view binding and Kotlin synthetic accessors. Of those, I prefer view binding. For Jetpack Compose, the way you create UIs is completely different, such that `findViewById()` and things that layer atop of it (data binding, view binding, Kotlin synthetic accessors) are no longer needed. – CommonsWare Oct 10 '20 at 12:50
  • Oh wow, Thanks bro! ill put Jetpack Compose and View Binding on my Sched for this month. Thanks a lot! – Branddd Oct 10 '20 at 12:56
  • 2
    @Branddd: Note that Jetpack Compose is still in an early alpha state. I would not recommend it to somebody new to Android and Kotlin at this time. For now, I recommend learning the classic `View` system. Bear in mind that even when Compose ships, it is not like all existing Android apps will vanish. We will be dealing with `View` for many years for existing projects, and so what you learn today will still be of value even after Compose becomes popular. – CommonsWare Oct 10 '20 at 12:59
  • "Personally, I recommend not investing in data binding. Jetpack Compose will make data binding obsolete in a year or so." well probably will need more time – Farid Jan 19 '23 at 12:14
  • @Farid: Agreed. Compose UI uptake hasn't been as aggressive as I expected. – CommonsWare Jan 19 '23 at 12:49
2

One month later, I found this trick:

android:text="@{`` + viewModel.currentStudent.age}"     //"``" is key point!! Not single/double quote
Sam Chen
  • 7,597
  • 2
  • 40
  • 73