Created
July 19, 2012 14:20
-
-
Save peterkuterna/3144266 to your computer and use it in GitHub Desktop.
A FragmentPagerAdapter that exposes data from a Cursor
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 com.example; | |
import android.content.Context; | |
import android.database.Cursor; | |
import android.support.v4.app.Fragment; | |
import android.support.v4.app.FragmentManager; | |
import android.support.v4.app.FragmentPagerAdapter; | |
import android.util.SparseIntArray; | |
import android.view.ViewGroup; | |
import java.util.HashMap; | |
public abstract class CursorFragmentPagerAdapter extends FragmentPagerAdapter { | |
protected boolean mDataValid; | |
protected Cursor mCursor; | |
protected Context mContext; | |
protected SparseIntArray mItemPositions; | |
protected HashMap<Object, Integer> mObjectMap; | |
protected int mRowIDColumn; | |
public CursorFragmentPagerAdapter(Context context, FragmentManager fm, Cursor cursor) { | |
super(fm); | |
init(context, cursor); | |
} | |
void init(Context context, Cursor c) { | |
mObjectMap = new HashMap<Object, Integer>(); | |
boolean cursorPresent = c != null; | |
mCursor = c; | |
mDataValid = cursorPresent; | |
mContext = context; | |
mRowIDColumn = cursorPresent ? c.getColumnIndexOrThrow("_id") : -1; | |
} | |
public Cursor getCursor() { | |
return mCursor; | |
} | |
@Override | |
public int getItemPosition(Object object) { | |
Integer rowId = mObjectMap.get(object); | |
if (rowId != null && mItemPositions != null) { | |
return mItemPositions.get(rowId, POSITION_NONE); | |
} | |
return POSITION_NONE; | |
} | |
public void setItemPositions() { | |
mItemPositions = null; | |
if (mDataValid) { | |
int count = mCursor.getCount(); | |
mItemPositions = new SparseIntArray(count); | |
mCursor.moveToPosition(-1); | |
while (mCursor.moveToNext()) { | |
int rowId = mCursor.getInt(mRowIDColumn); | |
int cursorPos = mCursor.getPosition(); | |
mItemPositions.append(rowId, cursorPos); | |
} | |
} | |
} | |
@Override | |
public Fragment getItem(int position) { | |
if (mDataValid) { | |
mCursor.moveToPosition(position); | |
return getItem(mContext, mCursor); | |
} else { | |
return null; | |
} | |
} | |
@Override | |
public void destroyItem(ViewGroup container, int position, Object object) { | |
mObjectMap.remove(object); | |
super.destroyItem(container, position, object); | |
} | |
@Override | |
public Object instantiateItem(ViewGroup container, 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); | |
} | |
int rowId = mCursor.getInt(mRowIDColumn); | |
Object obj = super.instantiateItem(container, position); | |
mObjectMap.put(obj, Integer.valueOf(rowId)); | |
return obj; | |
} | |
public abstract Fragment getItem(Context context, Cursor cursor); | |
@Override | |
public int getCount() { | |
if (mDataValid) { | |
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; | |
mCursor = newCursor; | |
if (newCursor != null) { | |
mRowIDColumn = newCursor.getColumnIndexOrThrow("_id"); | |
mDataValid = true; | |
} else { | |
mRowIDColumn = -1; | |
mDataValid = false; | |
} | |
setItemPositions(); | |
notifyDataSetChanged(); | |
return oldCursor; | |
} | |
@Override | |
public long getItemId(int position) { | |
if (!mDataValid || !mCursor.moveToPosition(position)) { | |
return super.getItemId(position); | |
} | |
int rowId = mCursor.getInt(mRowIDColumn); | |
return rowId; | |
} | |
} |
Hey. Thanks for this @peterkuterna
I had some issues with data not updating on calling swapCursor
- changed as follows:
public Cursor swapCursor(Cursor newCursor) {
if (newCursor == mCursor) {
return null;
}
Cursor oldCursor = mCursor;
mCursor = newCursor;
if (newCursor != null) {
mRowIDColumn = newCursor.getColumnIndexOrThrow("_id");
mDataValid = true;
} else {
mRowIDColumn = -1;
mDataValid = false;
}
setItemPositions();
if (mDataValid){
notifyDataSetChanged();
}
return oldCursor;
}
...if it helps anyone. Seems to work for me,
I forked this gist , with above change and subclassing of FragmentStatePagerAdapter
rather than FragmentPagerAdapter
- just removed getItemId(int pos)
Seem to work well. https://gist.github.com/aegis1980/95b757047749ae19c484
Thank you. It works fine.
P.S: Android is so feeble so we forced to reinvent the wheel for every 5 minites. And What is reason to believe it so great? I'm developing android apps for 4th year and I use third hand's codes everywhere and every case. Is that so?
Please how do i use this in my code
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
We fixed it with:
Moving the notifyDataSetChanged into the if-statement better mimics the CursorAdapter-behaviour also.