与 RecyclerView 进行数据绑定,其中每个项目 CheckBox
databinding with RecyclerView where each item CheckBox
我有 RecyclerView ,其中每个项目代表 CheckBox 和 EditText
当点击 CheckBox 时,EditText 的文本应该被删除,
我有 ObservableBoolean,它是 article.complete
我在 app:checkBoxChangeListener="@{article.complete}"
app:itemComplete="@{article.complete}"
中使用了它
除非我滚动 RecyclerView,然后单击 CheckBox,否则它会起作用,另一个项目的文本被删除
@BindingAdapter("itemComplete")
public static void bindItemComplete(EditText itemInput, boolean complete){
itemInput.setPaintFlags(complete ?
(itemInput.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG) : 0);
}
Article.java
public class Article{
public final ObservableBoolean complete = new ObservableBoolean();
}
xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="se.ica.handla.articles.ArticleListViewModel" />
<variable
name="article"
type="se.ica.handla.models.articles.Article" />
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:itemComplete="@{article.complete}"
/>
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={article.complete}" />
</android.support.constraint.ConstraintLayout>
</layout>
正如我在评论中所写,我建议您使用双向数据绑定。
你完全可以删除这个BindingAdapter
:
@BindingAdapter(value = {"checkBoxChangeListener", "article"}, requireAll = false)
public static void bindCheckBox(CheckBox view, final ObservableBoolean checked, Article article) {
if (view.getTag(R.id.binded) == null) {
//Here you are setting the attributes to your *view* and
//decouple it from your article. It does not reference it,
//the properties (isChecked) isnow on the view.
//So when your view gets recycled when you scroll,
//it still has the property you set the last time -
//and not from your current article, which is displayed now in the view.
view.setTag(R.id.binded, true);
view.setOnCheckedChangeListener((buttonView, isChecked) -> checked.set(isChecked));}
}
}
正如您已经发现的那样,您的 xml 现在应该看起来像这样,使用双向数据绑定:
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:itemComplete="@{article.complete}"
/>
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={article.complete}" //@={} for Two-Way Databinding
/>
我有 RecyclerView ,其中每个项目代表 CheckBox 和 EditText
当点击 CheckBox 时,EditText 的文本应该被删除,
我有 ObservableBoolean,它是 article.complete
我在 app:checkBoxChangeListener="@{article.complete}"
app:itemComplete="@{article.complete}"
除非我滚动 RecyclerView,然后单击 CheckBox,否则它会起作用,另一个项目的文本被删除
@BindingAdapter("itemComplete")
public static void bindItemComplete(EditText itemInput, boolean complete){
itemInput.setPaintFlags(complete ?
(itemInput.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG) : 0);
}
Article.java
public class Article{
public final ObservableBoolean complete = new ObservableBoolean();
}
xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="se.ica.handla.articles.ArticleListViewModel" />
<variable
name="article"
type="se.ica.handla.models.articles.Article" />
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:itemComplete="@{article.complete}"
/>
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={article.complete}" />
</android.support.constraint.ConstraintLayout>
</layout>
正如我在评论中所写,我建议您使用双向数据绑定。
你完全可以删除这个BindingAdapter
:
@BindingAdapter(value = {"checkBoxChangeListener", "article"}, requireAll = false)
public static void bindCheckBox(CheckBox view, final ObservableBoolean checked, Article article) {
if (view.getTag(R.id.binded) == null) {
//Here you are setting the attributes to your *view* and
//decouple it from your article. It does not reference it,
//the properties (isChecked) isnow on the view.
//So when your view gets recycled when you scroll,
//it still has the property you set the last time -
//and not from your current article, which is displayed now in the view.
view.setTag(R.id.binded, true);
view.setOnCheckedChangeListener((buttonView, isChecked) -> checked.set(isChecked));}
}
}
正如您已经发现的那样,您的 xml 现在应该看起来像这样,使用双向数据绑定:
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:itemComplete="@{article.complete}"
/>
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={article.complete}" //@={} for Two-Way Databinding
/>