Search code examples
androidandroid-recyclerviewandroid-databinding

Flicker image when bind image in RecyclerView item using DataBinding


I use DataBinding for bind image in RecyclerView item like the code below then it make image flicker when I reload all RecyclerView (by notifyDataSetChange)
If I don't use DataBinding and just set image normally, the image don't flicker What did I do wrong with DataBinding ? Any help or suggestion would be great appreciated

My RecyclerView adapter code

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);
    }
}

My item 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

Demo Project: https://drive.google.com/file/d/0B_poNaia6t8kVlBfSGJ4QU9uZHc/view


Solution

  • I think the step you're missing is that you must use executePendingBindings():

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        // Normally, you'd do the binding here, but yours is static.
        holder.mBinding.executePendingBindings();
    }
    

    For an article on this topic: https://medium.com/google-developers/android-data-binding-recyclerview-db7c40d9f0e4#.24tuxwvsh