使用DataBinding在RecyclerView项目中绑定图像时闪烁图像

时间:2017-02-09 04:08:54

标签: android android-recyclerview android-databinding

我在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>

enter image description here

演示项目:https://drive.google.com/file/d/0B_poNaia6t8kVlBfSGJ4QU9uZHc/view

2 个答案:

答案 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()重新刷新 但是在那个适配器中我可以用另一种方式强制刷新。所以我对此有所了解。希望这会有所帮助......