I am trying to get a recycler viewer with a cursor adapter. I seem to miss important points, so my view gets some of the data repeated instead of all the data at once. Can anyone who knows about this issue review this code and help me find the problem?
import android.content.Context;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.net.Uri;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.Random;
import amistore.nativeapps.com.amistore.data.ProductContract;
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.ProductViewHolder> {
private final String LOG_TAG = RVAdapter.class.getName();
// PATCH: Because RecyclerView.Adapter in its current form doesn't natively support
// cursors, we "wrap" a CursorAdapter that will do all teh job
// for us
CursorAdapter mCursorAdapter;
private Cursor mCursor;
protected boolean mDataValid;
private DataSetObserver mDataSetObserver;
private Context mContext;
private ProductViewHolder pvh;
private int mRowIdColumn;
//List<Product> products;
public RVAdapter(Context context, Cursor cursor, String locationSetting) {
mContext = context;
// Sort order: Ascending, by date.
String sortOrder = ProductContract.ProductEntry.COLUMN_DATE + " ASC";
Uri productForLocationUri = ProductContract.ProductEntry.buildProductLocationWithStartDate(
locationSetting, System.currentTimeMillis());
// Students: Uncomment the next lines to display what what you stored in the bulkInsert
mCursor = mContext.getContentResolver().query(productForLocationUri,
null, null, null, sortOrder);
Log.d(LOG_TAG, "Const. reached ");
Log.d(LOG_TAG, " mCursor " + Integer.valueOf(mCursor.getCount()).toString());
mCursorAdapter = new CursorAdapter(mContext, mCursor, 0) {
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// Inflate the view
Log.d("CHEKC", "newView reached ");
//Choose the layout type
// int viewType = getItemViewType(cursor.getPosition());
// int layoutId = -1;
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
// View view = LayoutInflater.from(context).inflate(layoutId, parent, false);
pvh = new ProductViewHolder(view);
view.setTag(pvh);
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
Log.d("CHEKC", "BindView reached");
// Binding operations
ProductViewHolder viewHolder = (ProductViewHolder) view.getTag();
//int viewType = getItemViewType(cursor.getPosition());
// Read ImagePath from cursor
String Image_Path = cursor.getString(ShopFragment.COL_PRODUCT_IMAGE);
Log.d(LOG_TAG, "path: " + Image_Path );
String Price = cursor.getString(ShopFragment.COL_PRODUCT_PRICE);
viewHolder.productPrice.setText("US $" + Price);
int i = new Random(50).nextInt();
int height = new Random(i).nextInt(50) + 500;
//Download image using picasso library
Picasso.with(mContext).load(Image_Path)
.resize(500, height)
.error(R.drawable.placeholder)
.placeholder(R.drawable.placeholder)
.into(viewHolder.productPhoto);
}
};
mDataSetObserver = new NotifyingDataSetObserver();
if (mCursor != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
boolean cursorPresent = (mCursor != null);
mDataValid = cursorPresent;
mRowIdColumn = cursorPresent ? mCursor.getColumnIndexOrThrow("_id") : -1;
setHasStableIds(true);
}
/**
* Change the underlying cursor to a new cursor. If there is an existing cursor it will be
* closed.
*/
public void changeCursor(Cursor cursor) {
Cursor old = swapCursor(cursor);
if (old != null) {
old.close();
}
}
/**
* Swap in a new Cursor, returning the old Cursor. Unlike
* {@link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em>
* closed.
*/
public Cursor swapCursor(Cursor newCursor) {
if (newCursor == mCursor) {
return null;
}
final Cursor oldCursor = mCursor;
if (oldCursor != null && mDataSetObserver != null) {
oldCursor.unregisterDataSetObserver(mDataSetObserver);
}
mCursor = newCursor;
if (mCursor != null) {
if (mDataSetObserver != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
mRowIdColumn = newCursor.getColumnIndexOrThrow("_id");
mDataValid = true;
notifyDataSetChanged();
} else {
mRowIdColumn = -1;
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
return oldCursor;
}
private class NotifyingDataSetObserver extends DataSetObserver {
@Override
public void onChanged() {
super.onChanged();
mDataValid = true;
notifyDataSetChanged();
}
@Override
public void onInvalidated() {
super.onInvalidated();
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
}
public static class ProductViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView productPrice;
ImageView productPhoto;
ProductViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.cv);
productPrice = (TextView) itemView.findViewById(R.id.product_price);
productPhoto = (ImageView) itemView.findViewById(R.id.product_photo);
}
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
@Override
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int i) {
// View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
View v = mCursorAdapter.newView(mContext, mCursorAdapter.getCursor(), parent);
pvh = new ProductViewHolder(v);
return pvh;
}
@Override
public void onBindViewHolder(ProductViewHolder holder, int position) {
// Passing the binding operation to cursor loader
mCursorAdapter.getCursor().moveToPosition(position); //EDITED: added this line as suggested in the comments below, thanks :)
mCursorAdapter.bindView(holder.itemView, mContext, mCursorAdapter.getCursor());
}
@Override
public int getItemCount() {
Log.d("ITEM COUNT ", Integer.valueOf(mCursorAdapter.getCount()).toString());
return mCursorAdapter.getCount();
}
}