代码之家  ›  专栏  ›  技术社区  ›  CommonsWare

如何让数据绑定表达式对同一布局中的EditText中的更改作出反应?

  •  1
  • CommonsWare  · 技术社区  · 6 年前

    假设我有一个 EditText 身份证是 foo . 在同一布局资源的其他地方,我有一个 Button ,我想启用 按钮 只有在文本中有文本时

    我以为这样行得通:

            <Button
                android:id="@+id/bar"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="@{listener}"
                android:text="Um, hi!"
                android:enabled="@{foo.text.length > 0}" />
    

    生成的绑定类确实调用 setEnabled() bar 根据文章的长度 ... 但只有在 executeBindings() 不会根据用户在 编辑文本 .

    1 回复  |  直到 6 年前
        1
  •  4
  •   CommonsWare    6 年前

    更新

    只要改变 foo.text.length foo.text.length() .


    一些要点,也许你错过了。

    1使用 BaseObservable

    model extends 基本可观测 那你需要 food.text @Bindable .

    public class UserBaseObservable extends BaseObservable {
        private String name;
    
        @Bindable
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
            notifyPropertyChanged(BR.name);
        }
    }
    

    原因 当你使用 text.length 然后需要在更改时调用所有依赖元素。因为 文本长度 是不可观察的,所以您需要手动调用它。生成的绑定类调用 setName(value) 但它没有改变 文本长度 从属视图。

    2使用 MutableLiveData

    如果你使用 可变LiveData LifeCycleOwner

        binding.setLifecycleOwner(this);
    

    ObservableField (最短接近)

    另一个简单的方法是使用 可观测场 foo.text

    我说轻松点 因为你不需要进入这个领域 Bindable

    public class UserObservableField {
        private ObservableField<String> name = new ObservableField<>();
    
        public ObservableField<String> getName() {
            return name;
        }
    
        public void setName(ObservableField<String> name) {
            this.name = name;
        }
    }
    

    我创建了一个样本,其中3个解决方案,都在工作!

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        >
    
        <data>
    
            <variable
                name="userObservableField"
                type="com.innovanathinklabs.sample.activities.LoginActivity.UserObservableField"/>
    
            <variable
                name="userMutable"
                type="com.innovanathinklabs.sample.activities.LoginActivity.UserMutable"/>
    
            <variable
                name="userBaseObservable"
                type="com.innovanathinklabs.sample.activities.LoginActivity.UserBaseObservable"/>
    
        </data>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:padding="20dp">
    
            <EditText
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:hint="Enter your name"
                android:text="@={userObservableField.name}"/>
    
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:enabled="@{userObservableField.name.length()>0}"
                android:text="Proceed"/>
    
            <EditText
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:hint="Enter your name"
                android:text="@={userMutable.name}"
                />
    
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:enabled="@{userMutable.name.length()>0}"
                android:text="Proceed"/>
    
            <EditText
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:hint="Enter your name"
                android:text="@={userBaseObservable.name}"/>
    
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:enabled="@{userBaseObservable.name.length()>0}"
                android:text="Proceed"/>
    
        </LinearLayout>
    </layout>
    

    public class LoginActivity extends AppCompatActivity {
        ActivityLoginBinding binding;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            binding = DataBindingUtil.setContentView(this, R.layout.activity_login);
            binding.setLifecycleOwner(this); // necessary for LiveData to work
            binding.setUserObservableField(new UserObservableField());
            binding.setUserBaseObservable(new UserBaseObservable());
            binding.setUserMutable(new UserMutable());
        }
    
        public static class UserObservableField {
            private ObservableField<String> name = new ObservableField<>();
    
            public ObservableField<String> getName() {
                return name;
            }
    
            public void setName(ObservableField<String> name) {
                this.name = name;
            }
        }
    
    
        public static class UserBaseObservable extends BaseObservable {
            private String name;
    
            // necessary for updating button
            @Bindable
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
                notifyPropertyChanged(BR.name);
            }
        }
    
    
        public static class UserMutable {
            private MutableLiveData<String> name = new MutableLiveData<>();
    
            public MutableLiveData<String> getName() {
                return name;
            }
    
            public void setName(MutableLiveData<String> name) {
                this.name = name;
            }
        }
    }
    

    我把所有的模型都放在活动中。我试着解释得很好,但是如果你有任何困惑,你可以发表评论。

    output image

        2
  •  0
  •   Rosh R    5 年前

    android:afterTextChanged 属性并执行以下操作 android:afterTextChanged="@{(text) -> viewmodel.onSomethingChanged(text)}" . 这样就不会公开MutableLiveData对象。