L'implémentation de la liaison bidirectionnelle avec un type de données Integer me pose problème.
public class User {
private String firstName;
private String lastName;
private int age;
public User() {}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return this.firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return this.lastName;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android">
<data class="UserDataBinding">
<variable
name="user"
type="com.databinding.model.User" />
</data>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical"
Android:padding="@dimen/activity_horizontal_margin">
<EditText Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="@={user.firstName}" />
<EditText Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="@={user.lastName}" />
<EditText Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="@={user.age}" />
</LinearLayout>
</layout>
Malheureusement, ça me donne l'erreur
"Erreur: (52, 17) Impossible de trouver le getter pour l'attribut" Android: text " Avec le type de valeur Java.lang.Integer sur Android.support.design.widget.TextInputEditText."
Si je change le texte de l'attribut en
<EditText Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="@={Integer.toString(user.age)}" />
alors j'obtiens l'erreur
"Erreur: impossible de générer des classeurs de vue Java.lang.NullPointerException"
Appréciez toute aide sur ceci.
UPDATE: Il semble qu'il y ait eu une autre erreur juste après l'erreur mentionnée ci-dessus.
ne peut pas générer de classeurs de vue Java.lang.NullPointerException
Je ne sais pas pourquoi cela me donne du NPE même si l'application n'a pas encore démarré.
Eh bien, six mois plus tard, mais je peux peut-être aider quelqu'un.
Vous pouvez faire ce truc simple:
Android:text="@={`` + mObject.someNumber}"
OBS.: Vous avez besoin d'au moins Android Studio 2.3
D'une manière ou d'une autre, j'ai obtenu ce résultat en utilisant BindingAdapter et InverseBindingAdapter.
public class User {
private String firstName;
private String lastName;
private int age;
public User() {}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return this.firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return this.lastName;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
@BindingAdapter("Android:text")
public static void setText(TextView view, int value) {
view.setText(Integer.toString(value));
}
@InverseBindingAdapter(attribute = "Android:text")
public static int getText(TextView view) {
return Integer.parseInt(view.getText().toString());
}
}
J'espère que cela aidera quelqu'un d'autre aussi.
La réponse précédente, accompagnée du commentaire de Roberto Leinardi, a parfaitement fonctionné pour moi! Il me suffit d'ajouter que le chèque nul devrait être appliqué au chèque de Roberto:
@BindingAdapter("Android:text")
public static void setText(TextView view, int value) {
view.setText(Integer.toString(value));
}
@BindingAdapter("Android:text")
public static void setText(TextView view, int value) {
if (view.getText() != null
&& ( !view.getText().toString().isEmpty() )
&& Integer.parseInt(view.getText().toString()) != value) {
view.setText(Integer.toString(value));
}
}
J'ai réussi à utiliser Integer.toString (...), en effectuant l'importation, comme ceci:
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools">
<data>
<import type="Java.lang.Integer" />
<variable ... />
</data>
Voici ma solution. C'est propre et simple. Si la mise en page nécessite String, donnez-lui une chaîne au lieu de int. Tout ce que vous avez à faire est de créer un setter et un getter avec le type String et de les utiliser pour se lier à l'interface utilisateur pendant qu'un setter et un getter normal font la chose normale!
Un code complet!
Ma classe POJO (Mydata.Java). getAgeString
et setAgeString
sont les méthodes ui effectuant la conversion. Notez que je mets @Bindable
sur getAgeString
. alors, je vais utiliser ageString
package com.databindingnumber;
import Android.databinding.BaseObservable;
import Android.databinding.Bindable;
public class MyData extends BaseObservable{
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
if(this.age != age) {
this.age = age;
notifyPropertyChanged(BR.ageString);//NOTE: ui is using ageString !
}
}
@Bindable
public String getAgeString() {
return Integer.toString(age);
}
public void setAgeString(String ageString) {
try {
int val = Integer.parseInt(ageString);
this.setAge(val);
}catch(NumberFormatException ex){
this.setAge(0);//default value
}
}
}
Le fichier de mise en page (activity_main.xml). utilisez une liaison bidirectionnelle normale avec @=
mais utilisez ageString
au lieu de age
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android">
<data>
<variable name="foo" type="com.databindingnumber.MyData"/>
</data>
<EditText
Android:layout_width="100dp"
Android:layout_height="wrap_content"
Android:inputType="numberSigned"
Android:text="@={foo.ageString}" />
</layout>
Fichier MainActivity.Java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setFoo(new MyData());
}
}
J'espère que cela aidera à quelqu'un!
Ajoutez ce qui suit dans strings.xml:
<resources>
<string name="_int">%d</string>
</resources>
Ensuite, vous pouvez faire:
<EditText
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="@{@string/_int(user.age)}" />