我在使用Integer数据类型实现双向绑定时遇到了一些问题。
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>
不幸的是,它给了我错误
“错误:(52,17)无法找到属性'android:text'的getter 值类型为java.lang.Integer on android.support.design.widget.TextInputEditText。 “
如果我将属性文本更改为
<EditText android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@={Integer.toString(user.age)}" />
然后我收到错误
“错误:无法生成视图绑定器java.lang.NullPointerException”
感谢您的任何帮助。
更新:在上述错误之后,似乎还有另一个错误。
无法生成视图绑定器java.lang.NullPointerException
即使应用还没有开始,也不确定为什么它会给我NPE。
答案 0 :(得分:33)
好吧,六个月后,但也许我可以帮助别人。
你可以做这个简单的伎俩:
android:text="@={`` + mObject.someNumber}"
OBS :您至少需要 Android Studio 2.3
答案 1 :(得分:13)
不知怎的,我使用BindingAdapter和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());
}
}
希望这对其他人也有帮助。
答案 2 :(得分:6)
android:text="@{String.valueOf(Integer)}"
答案 3 :(得分:4)
之前的回答以及Roberto Leinardi的评论对我来说非常合适! 我只需要补充的是,应该对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));
}
}
答案 4 :(得分:4)
我设法使用Integer.toString(...)进行导入,如下所示:
<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>
答案 5 :(得分:1)
这是我的解决方案。它干净简单。如果layout需要String,只需给它一个String而不是int。你所要做的就是用String类型创建一个setter和getter,并使用它们绑定到ui,而普通的setter和getter做正常的事情!
完整的代码!
我的POJO课程(Mydata.java)。 getAgeString
和setAgeString
是进行转换的ui方法。请注意,我将@Bindable
放在getAgeString
上。所以ui将使用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
}
}
}
布局文件(activity_main.xml)。使用@=
的常规双向绑定,但使用ageString
代替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>
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());
}
}
希望这会对某人有所帮助!
答案 6 :(得分:1)
这可能会帮助需要使用双向数据绑定和Kotlin的某些人。
DataBindingConverter.kt
class DataBindingConverter {
companion object {
@InverseMethod("convertStringToInteger")
@JvmStatic
fun convertIntegerToString(value: String): Int? {
if (TextUtils.isEmpty(value) || !TextUtils.isDigitsOnly(value)) {
return null
}
return value.toIntOrNull()
}
@JvmStatic
fun convertStringToInteger(value: Int?): String {
return value?.toString() ?: ""
}
}
}
在您的视图中导入该类
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="com.package.DataBindingConverter" />
</data>
.....
将其绑定到textview
<EditText
...
android:text="@={DataBindingConverter.convertStringToInteger(ViewModel.user.age)}" />
答案 7 :(得分:0)
在strings.xml中添加以下内容:
<resources>
<string name="_int">%d</string>
</resources>
那么您可以做:
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{@string/_int(user.age)}" />
答案 8 :(得分:0)
使用@xdbas解决方案的方式
DataBindingConverter.kt
class DataBindingConverters {
companion object {
@InverseMethod("convertIntegerToString")
@JvmStatic
fun convertStringToInteger(value: String): Int? {
if (TextUtils.isEmpty(value) || !TextUtils.isDigitsOnly(value)) {
return null
}
return value.toIntOrNull()
}
@JvmStatic
fun convertIntegerToString(value: Int?): String {
return value?.toString() ?: ""
}
}
}
XML导入
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="com.package.DataBindingConverter" />
</data>
.....
绑定到textView
<EditText
...
android:text="@={DataBindingConverter.convertStringToInteger(ViewModel.user.age)}" />
也许我应该编辑他的答案,但是我不知道这是否对他不起作用。