代码之家  ›  专栏  ›  技术社区  ›  live-love

双向数据绑定不更新UI

  •  2
  • live-love  · 技术社区  · 7 年前

    我试图理解为什么设置值不会自动刷新UI。如果我调用绑定。setItem,UI刷新。

    我知道binding对象包含更新的值,但在设置项后UI不会刷新。名称和项目。已选中。

    我做错了什么?我是否需要每次调用setItem来刷新UI?我认为这是不必要的,因为UI会在设置值后自动更新。

    项目java:

    public class Item  {
        public String name;
        public Boolean checked;
    }
    

    主要活动。java:

    public class MainActivity extends AppCompatActivity {
    
        public Item item;
        ActivityMainBinding binding;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            item = new Item();
            item.checked = true;
            item.name = "a";
    
            binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
            binding.setItem(item);
        }
    
        public void button_onClick(View v) {
            item.checked = !item.checked;
            item.name = item.name  + "a";
            ///binding.setItem(item); --> ??? this updates UI, do I need to call this to refresh UI everytime???
        }
    }
    

    activity\u main。xml:

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
        <data>
            <variable
                name="item"
                type="com.example.abc.twowaydatabinding.Item" />
        </data>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
            <TextView
                android:id="@+id/tv_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@={item.name}"
                android:textSize="20sp" />
    
    
            <Switch
                android:id="@+id/switch_test"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="@={item.checked}" />
    
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="change"
                android:onClick="button_onClick"/>
    
        </LinearLayout>
    </layout>
    

    建筑格拉德尔:

    android {
    ...
        dataBinding{
            enabled=true
        }
    
    }
    
    3 回复  |  直到 7 年前
        1
  •  4
  •   Ben P.    7 年前

    根据开发商指南:

    任何普通的旧Java对象(POJO)都可以用于数据绑定,但修改POJO不会导致UI更新。

    您可以遵循《开发人员指南》的“可观察对象”部分,允许修改对象以更新UI。

    https://developer.android.com/topic/libraries/data-binding/index.html#data_objects

        2
  •  2
  •   Raghunandan    7 年前

    如前所述,使用ObservableFields

    public ObservableField<Boolean> checked = new ObservableField<>();
    
    public ObservableField<String> name = new ObservableField<>();
    

    并将MainActivity更改为

        item = new Item();
        item.checked.set(true);
        item.name.set("a");
    
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.setItem(item);
    }
    
    public void button_onClick(View v) {
    
        item.checked.set(!(item.checked.get()));
        item.name.set(item.name.get()  + "a");
    
    }
    

    顺便说一下,您可以查看关于数据绑定的博客文章系列 https://medium.com/google-developers/android-data-binding-2-way-your-way-ccac20f6313 还有这个 https://medium.com/@fabioCollini/android-data-binding-f9f9d3afc761

        3
  •  1
  •   live-love    7 年前

    为了更新UI,需要观察字段。只需更新我的更改:

    import android.databinding.BaseObservable;
    import android.databinding.Bindable;
    
    public class Item extends BaseObservable {
        private String name;
        private Boolean checked;
        @Bindable
        public String getName() {
            return this.name;
        }
        @Bindable
        public Boolean getChecked() {
            return this.checked;
        }
        public void setName(String name) {
            this.name = name;
            notifyPropertyChanged(BR.name);
        }
        public void setChecked(Boolean checked) {
            this.checked = checked;
            notifyPropertyChanged(BR.checked);
        }
    }