patternjavaMajor
Custom CursorAdapter Design
Viewed 0 times
customdesigncursoradapter
Problem
Here's the code which I use for my Android custom cursor adapter which I use to bind data to my list view.
I know that there's another efficient way to do this which reuses the list item instantiated. Can someone tell me how?
public class MessageAdapter extends CursorAdapter {
private Cursor mCursor;
private Context mContext;
private final LayoutInflater mInflater;
public MessageAdapter(Context context, Cursor c) {
super(context, c);
mInflater=LayoutInflater.from(context);
mContext=context;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView mobileNo=(TextView)view.findViewById(R.id.mobileNolistitem);
mobileNo.setText(cursor.getString(cursor.getColumnIndex(TextMeDBAdapter.KEY_MOBILENO)));
TextView frequency=(TextView)view.findViewById(R.id.frequencylistitem);
frequency.setText(cursor.getString(cursor.getColumnIndex(TextMeDBAdapter.KEY_FREQUENCY)));
TextView rowid=(TextView)view.findViewById(R.id.rowidlistitem);
rowid.setText(cursor.getString(cursor.getColumnIndex(TextMeDBAdapter.KEY_ID)));
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final View view=mInflater.inflate(R.layout.message_list_item,parent,false);
return view;
}
}I know that there's another efficient way to do this which reuses the list item instantiated. Can someone tell me how?
Solution
This is exactly* the way you should be using your
In the case of the
Here is the code for
So you see, the method attempts to recycle the View that was passed in by checking
CursorAdapter. I'm sure you're referring to "recycling" the Views as talked about when overriding the getView() method of a BaseAdapter.In the case of the
CursorAdapter, all of that is taken care of for you so that just implementing newView() and bindView() fully takes advantage of the View recycling you're asking about.Here is the code for
CursorAdapter.getView():public View getView(int position, View convertView, ViewGroup parent) {
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);
}
View v;
if (convertView == null) {
v = newView(mContext, mCursor, parent);
} else {
v = convertView;
}
bindView(v, mContext, mCursor);
return v;
}So you see, the method attempts to recycle the View that was passed in by checking
convertView == null. If successful, it uses that View and simply calls bindView() to set it up appropriately. If convertView is null, it calls newView() to create the View, followed by bindView() to set it up. This is one of the rare instances on SE that I can say "You're doing it right!"- But to nitpick, there's really no reason to maintain a reference to your Context in
mContext- You're not using it anywhere and maintaining references to Contexts can lead to memory leaks, and ultimately the end of the world.
Code Snippets
public View getView(int position, View convertView, ViewGroup parent) {
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);
}
View v;
if (convertView == null) {
v = newView(mContext, mCursor, parent);
} else {
v = convertView;
}
bindView(v, mContext, mCursor);
return v;
}Context
StackExchange Code Review Q#1057, answer score: 24
Revisions (0)
No revisions yet.