Skip to content

Instantly share code, notes, and snippets.

@kyze8439690
Created October 19, 2014 06:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kyze8439690/8982011e142f17950120 to your computer and use it in GitHub Desktop.
Save kyze8439690/8982011e142f17950120 to your computer and use it in GitHub Desktop.
CursorAdapter used for RecyclerView
package me.yugy.cnbeta.widget;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.DataSetObservable;
import android.database.DataSetObserver;
import android.os.Handler;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
/**
* Created by yokmama on 2014/07/30.
*/
public abstract class CursorAdapter2<T extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<T> {
private final DataSetObservable mDataSetObservable = new DataSetObservable();
protected boolean mAutoRequery;
protected Cursor mCursor;
protected boolean mDataValid;
protected Context mContext;
protected int mRowIDColumn;
protected ChangeObserver mChangeObserver;
protected DataSetObserver mDataSetObserver = new MyDataSetObserver();
public CursorAdapter2(Context context, Cursor cursor) {
super();
init(context, cursor, true);
}
public CursorAdapter2(Context context, Cursor cursor, boolean autoRequery) {
super();
init(context, cursor, autoRequery);
}
protected void init(Context context, Cursor c, boolean autoRequery) {
boolean cursorPresent = c != null;
mAutoRequery = autoRequery;
mCursor = c;
mDataValid = cursorPresent;
mContext = context;
mRowIDColumn = cursorPresent ? c.getColumnIndexOrThrow("_id") : -1;
mChangeObserver = new ChangeObserver();
if (cursorPresent) {
c.registerContentObserver(mChangeObserver);
c.registerDataSetObserver(mDataSetObserver);
}
}
public Cursor getCursor() {
return mCursor;
}
@Override
public T onCreateViewHolder(ViewGroup viewGroup, int viewType) {
if (!mDataValid) {
throw new IllegalStateException("this should only be called when the cursor is valid");
}
return newViewHolder(viewGroup, viewType);
}
@Override
public void onBindViewHolder(T viewHolder, int position) {
if (!mDataValid) {
throw new IllegalStateException("this should only be called when the cursor is valid");
}
if (!mCursor.moveToPosition(position)) {
throw new IllegalStateException("couldn't move cursor to position " + position);
}
bindViewHolder(viewHolder, mCursor);
}
@Override
public int getItemCount() {
if (mDataValid && mCursor != null) {
return mCursor.getCount();
} else {
return 0;
}
}
public void changeCursor(Cursor cursor) {
Cursor old = swapCursor(cursor);
if (old != null) {
old.close();
}
}
public Cursor swapCursor(Cursor newCursor) {
if (newCursor == mCursor) {
return null;
}
Cursor oldCursor = mCursor;
if (oldCursor != null) {
if (mChangeObserver != null) oldCursor.unregisterContentObserver(mChangeObserver);
if (mDataSetObserver != null) oldCursor.unregisterDataSetObserver(mDataSetObserver);
}
mCursor = newCursor;
if (newCursor != null) {
if (mChangeObserver != null) newCursor.registerContentObserver(mChangeObserver);
if (mDataSetObserver != null) newCursor.registerDataSetObserver(mDataSetObserver);
mRowIDColumn = newCursor.getColumnIndexOrThrow("_id");
mDataValid = true;
// notify the observers about the new cursor
notifyDataSetChanged();
} else {
mRowIDColumn = -1;
mDataValid = false;
// notify the observers about the lack of a data set
notifyDataSetInvalidated();
}
return oldCursor;
}
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
public void notifyDataSetInvalidated() {
mDataSetObservable.notifyInvalidated();
}
protected void onContentChanged() {
if (mAutoRequery && mCursor != null && !mCursor.isClosed()) {
mDataValid = mCursor.requery();
}
}
public abstract T newViewHolder(ViewGroup parent, int viewType);
public abstract void bindViewHolder(T viewHolder, Cursor cursor);
private class ChangeObserver extends ContentObserver {
public ChangeObserver() {
super(new Handler());
}
@Override
public boolean deliverSelfNotifications() {
return true;
}
@Override
public void onChange(boolean selfChange) {
onContentChanged();
}
}
private class MyDataSetObserver extends DataSetObserver {
@Override
public void onChanged() {
mDataValid = true;
notifyDataSetChanged();
}
@Override
public void onInvalidated() {
mDataValid = false;
notifyDataSetInvalidated();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment