web-dev-qa-db-fra.com

La méthode d'inflation pour ma liaison est introuvable (avec Android, liaison de données)

J'utilise la liaison de données pour lier les mises en page de mon application Android.

J'ai configuré ma mise en page (my_custom.xml) et la classe de liaison est générée (MyCustomBinding), mais Android Studio ne semble pas trouver la méthode .inflate (...) de la classe Binding immédiatement, la marquant comme une erreur (texte rouge!).

Le code semble être correct cependant, car il compile et construit parfaitement dans un fichier APK.

Comment faire pour que Android Studio se mette à jour correctement?

Exemple de code:

Ceci est mon code de vue personnalisé:

    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");
    }
}

la mise en page est définie comme suit:

    <?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>

Et voici le problème: (surligné en rouge)

 enter image description here

19
treesAreEverywhere

Quelque chose ne se termine pas dans Android Studio car vous n'avez pas encore implémenté la liaison de données . Une fois que vous avez ajouté une variable à l'élément data de votre mise en page, la méthode inflate sera trouvée comme prévu. Cela dit, vous n’obtenez vraiment pas l’avantage de la liaison de données en définissant la valeur du champ de texte directement par le biais de la liaison. Vous devez plutôt définir un modèle de vue dans votre liaison, puis la laisser mettre à jour les vues en conséquence. Par exemple:

créer un modèle de vue:

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

et l'utiliser dans votre mise en page

<?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>

(notez la variable déclarée dans l'élément data et sa référence dans l'attribut text de TextView)

liez ensuite les deux dans votre vue personnalisée:

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);
    }
}

Bien sûr, il vaudrait probablement mieux que les données soient transmises via un programme de définition dans la classe de vue personnalisée, ou même depuis la vue du conteneur (voir http://developer.Android.com/tools/data- binding/guide.html # inclut )

9
Jeremy Dowdall

Vous pouvez essayer de définir un nom de classe personnalisé pour votre mise en page de liaison et de le référencer dans votre vue personnalisée pour indiquer clairement la mise en page que vous utilisez:

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

Si cela ne fonctionne pas, utilisez DataBindingUtil au lieu de MyCustomBinding, qui renvoie la classe DataBinding de base et possède une méthode inflate():

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

De la docs :

Parfois, la liaison ne peut pas être connue à l'avance. Dans de tels cas, la liaison peut être créée à l'aide de la classe DataBindingUtil: 

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

Vous n'avez pas besoin de ce genre de choses, DataBinding inclut la classe DataBindingUtils.

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