Created
October 19, 2014 06:07
-
-
Save kyze8439690/8982011e142f17950120 to your computer and use it in GitHub Desktop.
CursorAdapter used for RecyclerView
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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