我在RecyclerView项目中使用DataBinding
作为绑定图像,如下面的代码,然后当我重新加载所有RecyclerView(通过notifyDataSetChange)时,它会使图像闪烁
如果我不使用DataBinding
并且只是正常设置图像,则图像不会闪烁
我对DataBinding
做错了什么?任何帮助或建议将非常感谢
我的RecyclerView适配器代码
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
private Context mContext;
private List<String> list;
public static class MyViewHolder extends RecyclerView.ViewHolder {
ItemBinding mBinding;
public MyViewHolder(ItemBinding mBinding) {
super(mBinding.getRoot());
this.mBinding = mBinding;
mBinding.setViewHolder(this);
}
public int getSrc(){
return R.drawable.ic_launcher;
}
}
public RecyclerViewAdapter(Context context, List<String> moviesList) {
this.mContext = context;
this.list = moviesList;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ItemBinding binding =
DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.item,
parent, false);
return new MyViewHolder(binding);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
}
@Override
public int getItemCount() {
return list.size();
}
@BindingAdapter({ "src" })
public static void setImageSrc(ImageView view, int src) {
if (src != -1) view.setImageResource(src);
}
}
我的项目xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<data>
<variable
name="viewHolder"
type="example.toong.testreloadimageusingglidebynotifydatasetchangewithdatabinding.RecyclerViewAdapter.MyViewHolder"
/>
</data>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_holding_three_gradient_layer"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
app:src="@{viewHolder.src}"
/>
</LinearLayout>
</layout>
演示项目:https://drive.google.com/file/d/0B_poNaia6t8kVlBfSGJ4QU9uZHc/view
答案 0 :(得分:4)
我认为您缺少的步骤是您必须使用executePendingBindings()
:
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
// Normally, you'd do the binding here, but yours is static.
holder.mBinding.executePendingBindings();
}
有关此主题的文章: https://medium.com/google-developers/android-data-binding-recyclerview-db7c40d9f0e4#.24tuxwvsh
答案 1 :(得分:1)
有两种方法可以帮助你
1.编写自己的适配器
.notifyDataSetChange()。不能在数据绑定中工作
public class BindingRecyclerView {
public static abstract class ListAdapter<T, VH extends ViewHolder> extends RecyclerView.Adapter<VH> {
protected final LayoutInflater inflater;
protected final ObservableList<T> data;
private final AtomicInteger refs = new AtomicInteger();
private final ObservableList.OnListChangedCallback<ObservableList<T>> callback =
new ObservableList.OnListChangedCallback<ObservableList<T>>() {
@Override
public void onChanged(ObservableList<T> sender) {
notifyDataSetChanged();
}
@Override
public void onItemRangeChanged(ObservableList<T> sender,
int positionStart, int itemCount) {
notifyItemRangeChanged(positionStart, itemCount);
}
@Override
public void onItemRangeInserted(ObservableList<T> sender,
int positionStart, int itemCount) {
notifyItemRangeInserted(positionStart, itemCount);
}
@Override
public void onItemRangeMoved(ObservableList<T> sender,
int fromPosition, int toPosition, int itemCount) {
for (int i = 0; i < itemCount; i++) {
notifyItemMoved(fromPosition + i, toPosition + i);
}
}
@Override
public void onItemRangeRemoved(ObservableList<T> sender,
int positionStart, int itemCount) {
notifyItemRangeRemoved(positionStart, itemCount);
}
};
public ListAdapter(Context context, ObservableList<T> data) {
this.inflater = LayoutInflater.from(context);
this.data = data;
}
@Override
public int getItemCount() {
return data.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
if (refs.getAndIncrement() == 0) {
data.addOnListChangedCallback(callback);
}
}
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
if (refs.decrementAndGet() == 0) {
data.removeOnListChangedCallback(callback);
}
}
}
public static class ViewHolder<V extends ViewDataBinding> extends RecyclerView.ViewHolder {
public final V binding;
public ViewHolder(LayoutInflater inflater, @LayoutRes int layoutId, ViewGroup parent) {
this(DataBindingUtil.<V>inflate(inflater, layoutId, parent, false));
}
public ViewHolder(V binding) {
super(binding.getRoot());
this.binding = binding;
}
}}
2.当您刷新数据时,新适配器不会使用旧适配器。 它也可能有帮助
第一堂课并没有由我写。但它确实在我们的项目中得到了解决。 当我使用PageAdapter它也不会通过.notifyDataSetChange()重新刷新 但是在那个适配器中我可以用另一种方式强制刷新。所以我对此有所了解。希望这会有所帮助......