3

After upgrading to Gradle 2.3. My project cannot compile. I'm having the log in the console

incompatible types: ObservableInt cannot be converted to int

Look at the generated file

android.databinding.ObservableInt viewModelLoadingVisibility;
this.vLoading.getRoot().setVisibility(viewModelLoadingVisibility);

In xml file

<android.support.v7.widget.RecyclerView
    android:id="@+id/rvProducts"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:visibility="@{viewModel.contentVisibility}"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>

I tried in method in my binding class

@BindingAdapter("app:visibility")
public static void setViewVisible(View view, ObservableInt visible) {
        int visibility = visible.get();
        view.setVisibility(visibility);
}

and got log

warning: Application namespace for attribute app:visibility will be ignored.

public static void setViewVisible(View view, ObservableInt visible) {

warning: Use of ObservableField and primitive cousins directly as method parameters is deprecated and support will be removed soon. Use the contents as parameters instead in method public static void setViewVisible(android.view.View,android.databinding.ObservableInt)

public static void setViewVisible(View view, ObservableInt visible) {

Anyone encounters this?

Ken Zira
  • 1,170
  • 2
  • 10
  • 12

4 Answers4

2

This looks like a bug. Please file it. There are many tests and we don't expect this kind of regression. It is important that we get your specific example so we can be sure it is caught.

You can ignore the warnings for now.

The first is caused because of this:

@BindingAdapter("app:visibility")

You should use this instead:

@BindingAdapter("visibility")

The second is because we support ObservableInt as a parameter. You typically don't want to accept ObservableInt, but rather int instead. I'd love to see use cases where ObservableInt is necessary. We may just remove that warning and support it always or we may pull the plug on supporting ObservableInt as a parameter if there are no valid uses.

----- edit -----

I tested this with a little application and I didn't have any issue without any BindingAdapter. Here is the layout:

<layout>
    <data>
        <variable name="model" type="com.example.gmount.testobservableint.MyModel"/>
    </data>
    <android.support.constraint.ConstraintLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:onClick="@{model::clicked}"
            tools:context="com.example.gmount.testobservableint.MainActivity">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Hello World!"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                android:visibility="@{model.visibility}"
        />

    </android.support.constraint.ConstraintLayout>
</layout>

Here is my model:

public class MyModel {
    public final ObservableInt visibility = new ObservableInt(View.VISIBLE);

    public void clicked(View view) {
        int oldVisibility = visibility.get();
        int newVisibility = oldVisibility == View.VISIBLE ? View.GONE : View.VISIBLE;
        visibility.set(newVisibility);
    }
}

Even when I used a BindingAdapter taking an ObservableInt, it worked. Here's my BindingAdapter:

@BindingAdapter("visiblity")
public static void setVisibility(View view, ObservableInt visibility) {
    view.setVisibility(visibility.get());
}

And I changed the View's binding to be:

    <TextView ...
            app:visibility="@{model.visibility}"
    />

Is there something different about your viewModel?

George Mount
  • 20,708
  • 2
  • 73
  • 61
  • I did tried `@BindingAdapter("visibility")` and it did not work. I'm using data binding along with MVVM pattern to control the View state. For example, an error occurs, the `ErrorView` shows; the `ContentView` hides. It means an `ObservableInt` `errorViewVisibility.set(View.VISIBLE)`, and an `ObservableInt` `contentViewVisibility.set(View.GONE)`. Everything is okay with me on Gradle 2.2.3, then stopped on 2.3. – Ken Zira Mar 04 '17 at 03:26
  • Did you try BindingAdapter("android: visibility")? – George Mount Mar 04 '17 at 07:04
  • also, I assume that you also upgraded your gradle plugin line: `classpath com.android.tools.build:gradle:2.3.0` – George Mount Mar 05 '17 at 00:47
  • Yes, along with Android Studio – Ken Zira Mar 05 '17 at 03:01
  • Are you using data binding in any libraries? Perhaps they need to be recompiled. Data binding should be backward compatible. Also, could you post your view model? – George Mount Mar 05 '17 at 20:58
  • I'm using data binding in another library which is on Gradle 2.2.3. I'll update that library and give you feedback – Ken Zira Mar 06 '17 at 01:53
  • 1
    I ran into the same warning using an ObservableBoolean in BindingAdapter. When I came across this thread I changed my binding expression and adapter to pass the contained Boolean. But this results a new warning: Warning:Do not explicitly call 'get()' on ObservasbleFields in an expression. This support will be removed soon. 'viewModel.name.valid.get()' What is the correct way to address these deprecation warnings? – sidecarcat Jun 15 '17 at 14:17
1

You just have to add this to the bottom of your build.gradle dependencies:

apt 'com.android.databinding:compiler:2.3.0'
Christoph Mayr
  • 347
  • 3
  • 17
  • I tried this but it gave me a compilation error "Gradle DSL method not found: 'apt()' " – Dan Ponce Mar 03 '17 at 12:52
  • @DanPonce try using `annotationProcessor` instead of `apt` (or use `kapt` if you're using Kotlin) since `android-apt` is deprecated. I answered this to another question [here](http://stackoverflow.com/a/42868218/809572). – Josh Bowden Mar 18 '17 at 21:16
1

See this: https://stackoverflow.com/a/42711830/376829 regarding GoMobile update to version "+eb90329 Mar 7 2017" and GoBind plugin revert to version "0.2.6" (although the current version is "0.2.8")

Community
  • 1
  • 1
David Manpearl
  • 12,362
  • 8
  • 55
  • 72
0
 android:visibility="@{viewModel.contentVisibility}" 

remember this

dataBinding {
    enabled = true
}

re-download the library from the Support repository in the Android SDK manager.

Remario
  • 3,813
  • 2
  • 18
  • 25