Skip to content

Instantly share code, notes, and snippets.

@codeversed
Last active May 20, 2016 17:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codeversed/393cffee3d9d9303b15dd8a5d1074b04 to your computer and use it in GitHub Desktop.
Save codeversed/393cffee3d9d9303b15dd8a5d1074b04 to your computer and use it in GitHub Desktop.
RecyclerViewCursorAdapter and RecyclerViewCursorViewHolder
/**
* Adapter class that uses a CursorAdapter to display data in a RecyclerView.
*
*/
public abstract class RecyclerViewCursorAdapter<T extends RecyclerViewCursorViewHolder> extends RecyclerView.Adapter<T> {
/**
* The Context of the adapter.
*/
protected final Context mContext;
/**
* The record that is currently in a moving state.
* This helps handle the row move animations.
*/
protected long mMovingThreadID = -1;
protected int mMovingPosition = -1;
protected boolean mIsMoving = false;
/**
* The CursorAdapter to display data with.
*/
protected CursorAdapter mCursorAdapter;
// Define listener member variable
public OnItemClickListener listener;
// Define the listener interface
public interface OnItemClickListener {
void onItemClick(View itemView);
}
// Define the method that allows the parent activity or fragment to define the listener
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
/**
* ViewHolder object to bind Cursor data to. A class level variable is created to pass the
* ViewHolder between RecyclerView.Adapter.bindView() and CursorAdapter.bindView()
*/
private T mViewHolder;
/**
* Constructor.
* @param context The Context the Adapter is displayed in.
*/
protected RecyclerViewCursorAdapter(Context context) {
this.mContext = context;
}
/**
* Default implementation of the CursorAdapter for the scenario when only one view type is used.
* @param cursor The Cursor from which to get the data.
* @param flags Flags used to determine the behavior of the adapter.
* @param resource Resource ID for an XML layout to be inflated.
* @param attachToRoot Whether the inflated layout should be attached to the root view.
*/
protected void setupCursorAdapter(Cursor cursor, int flags, final int resource, final boolean attachToRoot) {
this.mCursorAdapter = new CursorAdapter(mContext, cursor, flags) {
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(resource, parent, attachToRoot);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
// Bind cursor to our ViewHolder
mViewHolder.bindCursor(cursor);
}
};
}
/**
* Swap the Cursor of the CursorAdapter and notify the RecyclerView.Adapter that data has
* changed.
* @param cursor The new Cursor representation of the data to be displayed.
*/
public void swapCursor(final Cursor cursor) {
if (cursor == null) return;
if (isMoving()) {
if (cursor instanceof ThreadCursor) {
ThreadCursor threadCursor = (ThreadCursor) cursor;
threadCursor.moveToFirst();
while (!threadCursor.isAfterLast()) {
if (threadCursor.getThreadId() == mMovingThreadID) {
notifyItemMoved(mMovingPosition, threadCursor.getPosition());
setIsMoving(false);
mCursorAdapter.swapCursor(cursor);
notifyItemChanged(threadCursor.getPosition());
notifyItemChanged(mMovingPosition);
break;
}
threadCursor.moveToNext();
}
} else {
PostCursor postCursor = (PostCursor) cursor;
postCursor.moveToFirst();
while (!postCursor.isAfterLast()) {
if (postCursor.getThreadId() == mMovingThreadID) {
notifyItemMoved(mMovingPosition, postCursor.getPosition());
setIsMoving(false);
mCursorAdapter.swapCursor(cursor);
notifyItemChanged(postCursor.getPosition());
notifyItemChanged(mMovingPosition);
break;
}
postCursor.moveToNext();
}
}
} else {
if (mCursorAdapter != null) {
mCursorAdapter.swapCursor(cursor);
notifyDataSetChanged();
}
}
}
/**
* The number of elements in the adapter is the number of elements in the CursorAdapter.
*/
@Override
public int getItemCount() {
return mCursorAdapter.getCount();
}
/**
* Sets the ViewHolder object.
* @param viewHolder The ViewHolder we will be binding data to.
*/
protected void setViewHolder(T viewHolder) {
this.mViewHolder = viewHolder;
}
public void setIsMoving(boolean isMoving) {
mIsMoving = isMoving;
}
public boolean isMoving() {
return mIsMoving;
}
public void setMovingItem(long threadID, int position) {
mMovingThreadID = threadID;
mMovingPosition = position;
setIsMoving(true);
}
public Cursor getCursor() {
return mCursorAdapter.getCursor();
}
public abstract class RecyclerViewCursorViewHolder extends RecyclerView.ViewHolder {
/**
* Constructor.
* @param view The root view of the ViewHolder.
*/
public RecyclerViewCursorViewHolder(View view) {
super(view);
}
/**
* Binds the information from a Cursor to the various UI elements of the ViewHolder.
* @param cursor A Cursor representation of the data to be displayed.
*/
public abstract void bindCursor(Cursor cursor);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment