web-dev-qa-db-ja.com

Android整数型の双方向バインディングにより、データバインディングが存在しません

整数データ型を使用した双方向バインディングの実装に問題があります。

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.support.design.widget.TextInputEditTextで値型Java.lang.Integerの属性「Android:text」のゲッターが見つかりません。」

属性テキストを

       <EditText Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="@={Integer.toString(user.age)}" />

その後、エラーが発生します

「エラー:ビューバインダーJava.lang.NullPointerExceptionを生成できません」

これに関するヘルプを感謝します。

更新:上記のエラーの直後に別のエラーが発生したようです。

ビューバインダーJava.lang.NullPointerExceptionを生成できません

アプリがまだ起動していなくても、なぜNPEが提供されるのかはわかりません。

26
ank

まあ、6か月後、多分私は誰かを助けることができます。

次の簡単なトリックを実行できます。

Android:text="@={`` + mObject.someNumber}"

[〜#〜] obs [〜#〜] .:少なくとも必要ですAndroid Studio 2.

39
Eduvm

どういうわけか、私は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());
    }
}

これが他の人にも役立つことを願っています。

13
ank

Android:text="@{String.valueOf(Integer)}"

7
Nimdokai

前の回答とRoberto Leinardiのコメントは完璧に機能しました!追加する必要があるのは、Robertoのチェックに対してnullチェックを行う必要があることです。

@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

次のように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>
4

これが私の解決策です。きれいでシンプルです。レイアウトにStringが必要な場合は、intではなくStringを指定します。あなたがしなければならないのは、String型のセッターとゲッターを作成し、それらを使用してUIにバインドする一方で、通常のセッターとゲッターが通常のことをしていることです!

完全なコード!

私のPOJOクラス(Mydata.Java)。 getAgeStringsetAgeStringは、変換を行うUIメソッドです。 getAgeString@Bindableを配置していることに注意してください。 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());
    }
}

これが誰かに役立つことを願っています!

1
mili

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)}" />
0