1.双向数据绑定(以xml为单位)
android:text="@={testStr}"
这在官方文档中没有提到(https://developer.android.com/topic/libraries/data-binding/index.html,这个页面通常会更新,现在可能会更改).但它可以将变量绑定到xml.
2. ObservableField属性
这里的例子(https://developer.android.com/topic/libraries/data-binding/index.html#observablefields)
private static class User { public final ObservableField<String> firstName = new ObservableField<>(); public final ObservableField<String> lastName = new ObservableField<>(); public final ObservableInt age = new ObservableInt(); }
3.将模型类扩展为BaSEObservable
private static class User extends BaSEObservable { private String firstName; private String lastName; @Bindable public String getFirstName() { return this.firstName; } @Bindable public String getLastName() { return this.lastName; } public void setFirstName(String firstName) { this.firstName = firstName; notifyPropertyChanged(BR.firstName); } public void setLastName(String lastName) { this.lastName = lastName; notifyPropertyChanged(BR.lastName); } }
模型类必须扩展到BaSEObservable类,并且getter方法必须使用“@Bindable”进行注释,并且setter方法需要使用绑定xml中的相应命名调用方法notifyPropertyChange().
我的问题是,我想知道三种绑定方法的缺点和优点.当然,我知道第一个会更容易.但是我在文档和某些网站上找到了一些时刻.它在下一刻消失了.官方文档未经任何明确公告而更改.我仍然想知道我应该使用第一种方法,所以我必须准备改变方法2或3.
Student_XML2WAY.java
public class Student_XML2WAY { private int age; private String name; public int getAge() { return age; } public void setAge(int pAge) { age = pAge; } public String getName() { return name; } public void setName(String pName) { name = pName; } }
Student_ObserField.java
public class Student_ObserField { private ObservableInt age; private ObservableField<String> name; public Student_ObserField() { age = new ObservableInt(); name = new ObservableField<>(); } public ObservableInt getAge() { return age; } public ObservableField<String> getName() { return name; } }
Student_Extend.java
public class Student_Extend extends BaSEObservable{ private int age; private String name; @Bindable public int getAge() { return age; } public void setAge(int pAge) { age = pAge; notifyPropertyChanged(BR.student3); } @Bindable public String getName() { return name; } public void setName(String pName) { name = pName; notifyPropertyChanged(BR.student3); } }
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <data> <variable name="student1" type="example.com.testerapplication.sp.bean.Student_XML2WAY"/> <variable name="student2" type="example.com.testerapplication.sp.bean.Student_ObserField"/> <variable name="student3" type="example.com.testerapplication.sp.bean.Student_Extend"/> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@={student1.name}"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{student2.name}"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{student3.name}"/> <Button android:id="@+id/btn1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="update"/> </LinearLayout> </layout>
活动类
public class MainActivity extends AppCompatActivity { private Student_XML2WAY mStudent1; private Student_ObserField mStudent2; private Student_Extend mStudent3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityMainBinding binding = DataBindingUtil.inflate(LayoutInflater.from(this),R.layout.activity_main,null,false); mStudent1 = new Student_XML2WAY(); mStudent1.setName("XML First"); mStudent2 = new Student_ObserField(); mStudent2.getName().set("ObserField Second"); mStudent3 = new Student_Extend(); mStudent3.setName("Extend Third"); binding.setStudent1(mStudent1); binding.setStudent2(mStudent2); binding.setStudent3(mStudent3); setContentView(binding.getRoot()); binding.btn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mStudent1.setName("Student1"); mStudent2.getName().set("Student2"); mStudent3.setName("Student3"); } }); } }
解决方法
如果我将直接访问模型,我将使用BaSEObservable,就像在Student_Extend中一样.我将在我的Activity中有一个Student_Extend实例,我将在onCreate中设置变量:
Student mStudent = new Student("John Doe",42); // binding.setStudent(mStudent); //later: mStudent.setAge(37);
如果正确实施,这也将改变UI(以及模型中)的年龄.
如果您不想直接访问模型并希望使用viewmodel,我可以使用ObervableFields:
public class Student { private String name; private int age; //Corresponding setters and getters } public class Studentviewmodel { private ObservableField<Student> mStudentField = new ObservableField<>(); //if I have a large model class,and only want to use some fields,//I create some getters (and setters,for the two way attributes) //Something like this: public int getAge() { return mStudentField.get().getAge(); } public void setAge(int newAge) { return mStudentField.get().setAge(newAge); } }
因此,我在Activity中创建了一个Studentviewmodel实例,并将其设置为绑定.伪xml看起来像这样:
<layout> <data> <variable name="studentviewmodel" type="locaction.of.Studentviewmodel"> <!-- or do an import --> </data> <EditText android:text="@={studentviewmodel.age}"/> </layout>
因此,viewmodel方法更“清晰”,因为您几乎将所有与视图有关的内容外包.把你的BindingAdapter,点击方法,转换器方法放在那里,保持你的活动干净.此外,您不直接更改您的模型.
对于简单的类和项目,这种方法可能过度. 原文链接:https://www.f2er.com/android/314660.html