web-dev-qa-db-de.com

Die Aufblasmethode für meine Bindung wird nicht gefunden (bei Android, Datenbindung).

Ich verwende Datenbindung, um die Layouts in meiner Android-App zu binden.

Ich habe mein Layout (my_custom.xml) eingerichtet und die Bindungsklasse wird generiert (MyCustomBinding), aber Android Studio scheint die .inflate (...) -Methode der Binding-Klasse nicht sofort zu finden und markiert dies als Fehler (roter Text!).

Der Code scheint jedoch korrekt zu sein, da er gut in eine APK kompiliert wird.

Wie bekomme ich die korrekte Aktualisierung von Android Studio?

Code-Beispiel:

Dies ist mein benutzerdefinierter Code zum Anzeigen:

    public class MyCustomView extends FrameLayout {
    public MyCustomView(Context context) {
        this(context, null, 0);
    }
    public MyCustomView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        MyCustomBinding binding = MyCustomBinding.inflate(inflater, this, true);
        binding.aButton.setText("Whatever");
    }
}

layout ist definiert als:

    <?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <data>
    </data>
    <FrameLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        >
        <TextView
            Android:id="@+id/a_button"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="Click me!"
            Android:padding="10dp"
            Android:background="#000"
            Android:textColor="#fff"
            Android:layout_gravity="center"
            />
    </FrameLayout>
</layout>

Und hier ist das Problem: (rot hervorgehoben)

 enter image description here

19

In Android Studio wird etwas nicht abgeschlossen, da Sie die Datenbindung nicht wirklich implementiert haben. Wenn Sie dem data-Element Ihres Layouts eine Variable hinzugefügt haben, wird die inflate-Methode wie erwartet gefunden. Das heißt, Sie profitieren wirklich nicht von der Datenbindung, wenn Sie den Wert des Textfelds direkt über die Bindung festlegen. Sie sollten stattdessen ein Ansichtsmodell in Ihrer Bindung festlegen und dann die Ansichten entsprechend aktualisieren lassen. Zum Beispiel:

erstellen Sie ein Ansichtsmodell:

public class MyViewModel {
    public final ObservableField<String> name;
    public MyViewModel(String name) {
        this.name = new ObservableField<>(name);
    }
}

und verwenden Sie es in Ihrem Layout

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <data>
        <variable name="model" type="com.victoriaschocolates.conceirge.MyViewModel" />
    </data>
    <FrameLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        >
        <TextView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="@{model.name}"
            Android:padding="10dp"
            Android:background="#000"
            Android:textColor="#fff"
            Android:layout_gravity="center"
            />
    </FrameLayout>
</layout>

(Beachten Sie die variable, die im data-Element deklariert ist, und wie sie im text-Attribut der TextView referenziert wird.)

binden Sie dann die beiden in Ihrer benutzerdefinierten Ansicht:

public class MyCustomView extends FrameLayout {

    public MyCustomView(Context context) {
        this(context, null, 0);
    }

    public MyCustomView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        MyCustomBinding binding = MyCustomBinding.inflate(inflater, this, true);
        MyViewModel model = new MyViewModel("Whatever");
        binding.setModel(model);
    }
}

Natürlich ist es wahrscheinlich noch besser, wenn die Daten durch einen Setter in der benutzerdefinierten Ansichtsklasse oder sogar aus der Containeransicht übergeben werden (siehe http://developer.Android.com/tools/data- Bindung/guide.html # umfasst )

9
Jeremy Dowdall

Sie können versuchen, einen benutzerdefinierten Klassennamen für Ihr Bindungslayout festzulegen und ihn in Ihrer benutzerdefinierten Ansicht zu referenzieren, um das verwendete Layout zu verdeutlichen:

<layout>
    <data class="MyCustomBinding">
    </data>
</layout>

Wenn dies nicht funktioniert, verwenden Sie DataBindingUtil anstelle von MyCustomBinding. Diese gibt die Basis-DataBinding-Klasse zurück und verfügt über eine inflate()-Methode:

MyCustomBinding binding = DataBindingUtil.inflate(inflater, this, true);

Aus den docs :

Manchmal ist die Bindung nicht im Voraus bekannt. In solchen Fällen kann die Bindung mithilfe der DataBindingUtil-Klasse erstellt werden: 

ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater, layoutId,
parent, attachToParent);
ViewDataBinding binding = DataBindingUtil.bindTo(viewRoot, layoutId);
3
yennsarah

Sie brauchen diese Art von Sachen nicht, DataBinding enthält die DataBindingUtils-Klasse.

public MyCustomView(Context context, AttributeSet attrs, int defStyle){
    super(context, attrs, defStyle);
    LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    MyCustomBinding binding = DataBindingUtil.inflate(inflater, this, true);
    binding.aButton.setText("Whatever");
}
0
Sardor Islomov