-
Notifications
You must be signed in to change notification settings - Fork 128
Using SquidCursorAdapter
SquidCursorAdapter is an abstract implementation of a BaseAdapter that wraps a SquidCursor. To construct a SquidCursorAdapter, you need to provide an empty "template" model object of the type to be used for the adapter. Generally this is done as follows:
public class PersonAdapter extends SquidCursorAdapter<Person> {
public PersonAdapter() {
super(new Person());
}
...
}
Optionally, you can pass a Property to the adapter constructor to specify a column that should be used to satisfy CursorAdapter's getItemId() contract. By default, the TableModel.ID property (the _id column) will be used for TableModels, but if your cursor is on ViewModels or does not have a column named _id, you are strongly recommended to specify a column to use for the id:
public class PeopleViewAdapter extends SquidCursorAdapter<ViewPerson> {
public PeopleViewAdapter() {
super(new ViewPerson(), ViewPerson.PERSON_ID);
}
...
}
If no id column is present in the cursor backing the adapter, it will return 0 for getItemId()
and false
for hasStableIds()
. If you do not provide an id column, it is recommended (although not mandatory) that you override getItemId() and hasStableIds() to calculate row ids differently.
The model object you pass to the adapter will be reused by the adapter for calls to getItem() (see Maximizing SquiDB performance for an example of reusing model objects). A reusable object is significantly better for performance, but it comes with some caveats. For example, you can't call getItem() on two different positions in the same scope:
// This is very bad, never do this
Person item0 = adapter.getItem(0);
Person item1 = adapter.getItem(1);
If you have code like the above example, item0 will contain the values at position 1. In fact, item0 == item1 because getItem populates your single template with the values at that row and then returns it.
If you need to access different rows from within a single scope, there are a couple ways to do it. One way is to clone the result of getItem:
Person item0 = adapter.getItem(0).clone();
Person item1 = adapter.getItem(1).clone();
// item0 and item1 are now distinct objects
// populated with data from their respective rows
Another is to just access the fields you need from other rows from the cursor directly:
Person item0 = adapter.getItem(0);
cursor.moveToPosition(1);
String personName1 = cursor.get(Person.NAME);
Finally, if you only need to access two rows at a time (e.g. the current row and the next one), you could define a second reusable template object:
public class PersonAdapter extends SquidCursorAdapter<Person> {
private Person extraTemplate = new Person();
...
public View getView(int position, View convertView, ViewGroup parent) {
Person person1 = getItem(position);
getCursor().moveToPosition(position + 1);
extraTemplate.readPropertiesFromCursor(getCursor());
...
}
}
To populate the adapter with data, call swapCursor() with an instance of SquidCursor:
PersonAdapter adapter = new PersonAdapter(context);
SquidCursor<Person> cursor = ...;
adapter.swapCursor(cursor);
If you are calling swapCursor() to populate the adapter from LoaderCallbacks.onLoadFinished(), you are encouraged to call swapCursor(null) in onLoaderReset().
See also: