Skip to content

Instantly share code, notes, and snippets.

@andreiverdes
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andreiverdes/c8229a68dc8ab33dec2e to your computer and use it in GitHub Desktop.
Save andreiverdes/c8229a68dc8ab33dec2e to your computer and use it in GitHub Desktop.
Faster alternative for OrmLiteCursorAdapter with OrmLite 4.48
package com.example.ormlite.cursor;
/**
* Created by andrei on 27/01/15.
*/
import android.content.Context;
import android.database.Cursor;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import com.example.ormlite.cursor.IBindable;
import java.util.HashMap;
public abstract class AwesomeCursorAdapter<T, ViewType extends View & IBindable<T>> extends CursorAdapter{
public static final int MODEL_TAG_ID = "MODEL_TAG_ID".hashCode();
private SparseArray<T> mPositionsMap;
public AwesomeCursorAdapter(Context context) {
super(context, null, false);
this.mPositionsMap = new SparseArray<>();
}
@SuppressWarnings("unchecked")
@Override public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
this.mPositionsMap.put(position % getCursor().getCount(), ((T) view.getTag(MODEL_TAG_ID)));
return view;
}
@Override public View newView(Context context, Cursor cursor, ViewGroup parent) {
ViewType view = getNewView(context, cursor, parent);
view.setTag(MODEL_TAG_ID, getNewModel());
return view;
}
@SuppressWarnings("unchecked")
@Override public final void bindView(View itemView, Context context, Cursor cursor) {
ViewType itemViewType = (ViewType) itemView;
T t = ((T) itemViewType.getTag(MODEL_TAG_ID));
this.mapCursorToModel(cursor, t);
itemViewType.bindView(context, t);
}
@Override public T getItem(int position) {
return mPositionsMap.get(position % getCursor().getCount());
}
/**
* Here is where you map the cursor values to your model
* @return The built and initialized model
*/
protected abstract void mapCursorToModel(Cursor pCursor, T pObject);
/**
* Should return a new View to be bond with the Model
* @return
*/
protected abstract ViewType getNewView(Context context, Cursor cursor, ViewGroup parent);
/**
* Should return a new Model
* @return a new model
*/
protected abstract T getNewModel();
}
package com.example.ormlite.cursor;
import android.content.Context;
import android.database.Cursor;
import android.view.ViewGroup;
import com.example.ormlite.cursor.DeviceModel;
import com.example.ormlite.cursor.AwesomeCursorAdapter;
/**
* Created by andrei on 30/01/15.
*/
public class DeviceCursorAdapter extends AwesomeCursorAdapter<DeviceModel, DeviceItemView> {
public DeviceCursorAdapter(Context context) {
super(context);
}
@Override protected void mapCursorToModel(Cursor pCursor, DeviceModel pDeviceModel) {
pDeviceModel.setName(pCursor.getString(pCursor.getColumnIndex("name")));
pDeviceModel.setId(pCursor.getLong(pCursor.getColumnIndex("id")));
//...here you can map your cursor to the model
}
@Override public DeviceItemView getNewView(Context context, Cursor cursor, ViewGroup parent) {
return new DeviceItemView(context);
}
@Override public DeviceModel getNewModel() {
return new DeviceModel();
}
}
package com.example.ormlite.cursor;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.ormlite.cursor.DeviceModel;
import com.example.ormlite.cursor.IBindable;
/**
* Created by andrei on 30/01/15.
*/
public class DeviceItemView extends LinearLayout implements IBindable<DeviceModel> {
private TextView mNameTextView;
private TextView mIdTextView;
public DeviceItemView(Context context) {
super(context);
}
public DeviceItemView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DeviceItemView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void init(Context pContext){
//inflate your view here and find the children views;
inflate(pContext, R.layout.your_awesome_device_item_view_layout, null);
this.mNameTextView = (TextView)this.findViewById(R.id.your_awesome_device_name_text_view);
this.mIdTextView = (TextView)this.findViewById(R.id.your_awesome_device_id_text_view);
}
@Override public void bindView(Context pContext, DeviceModel pModel) {
//here map your model to the view and do the actual binding...
this.mNameTextView.setText(pModel.getName());
this.mIdTextView.setTag(pModel.getIid());
}
}
package com.example.ormlite.cursor;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
/**
* Created by andrei on 30/01/15.
*/
@DatabaseTable
public class DeviceModel {
@DatabaseField(id = true, columnName = "_id") private long id;
@DatabaseField private String name;
public String getName() {
return name;
}
public void setName(String pName) {
name = pName;
}
public long getId() {
return id;
}
public void setId(long pId) {
id = pId;
}
}
package com.example.ormlite.cursor;
import android.content.Context;
/**
* Created by andrei on 26/01/15.
*/
public interface IBindable<T> {
public void bindView(Context pContext, T pModel);
}
package com.example.ormlite.cursor;
import android.content.AsyncTaskLoader;
import android.content.Context;
import android.database.Cursor;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.PreparedQuery;
import com.j256.ormlite.support.DatabaseConnection;
import com.j256.ormlite.android.AndroidCompiledStatement
import java.sql.SQLException;
import static com.j256.ormlite.stmt.StatementBuilder.StatementType.SELECT;
/**
* Cursor loader supported by later Android APIs that allows asynchronous content loading.
* Edited by andrei on 26/15/15
* @author emmby
*/
public class OrmLiteCursorLoader<T> extends AsyncTaskLoader<Cursor> {
protected Dao<T, ?> dao;
protected PreparedQuery<T> query;
protected Cursor cursor;
public OrmLiteCursorLoader(Context context, Dao<T, ?> dao, PreparedQuery<T> query) {
super(context);
this.dao = dao;
this.query = query;
// dao.registerObserver(this);
}
@Override
public Cursor loadInBackground() {
Cursor cursor;
try {
DatabaseConnection connection = dao.getConnectionSource().getReadOnlyConnection();
cursor = ((AndroidCompiledStatement) query.compile(connection, SELECT)).getCursor();
} catch (SQLException e) {
throw new RuntimeException(e);
}
// fill the cursor with results
cursor.getCount();
return cursor;
}
@Override
public void deliverResult(Cursor newCursor) {
if (isReset()) {
// an async query came in while the loader is stopped
if (newCursor != null) {
newCursor.close();
}
return;
}
Cursor oldCursor = cursor;
cursor = newCursor;
if (isStarted()) {
super.deliverResult(newCursor);
}
// close the old cursor if necessary
if (oldCursor != null && oldCursor != newCursor && !oldCursor.isClosed()) {
oldCursor.close();
}
}
@Override
protected void onStartLoading() {
if (cursor == null) {
forceLoad();
} else {
deliverResult(cursor);
if (takeContentChanged()) {
forceLoad();
}
}
}
@Override
protected void onStopLoading() {
cancelLoad();
}
@Override
public void onCanceled(Cursor cursor) {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
@Override
protected void onReset() {
super.onReset();
onStopLoading();
if (cursor != null) {
if (!cursor.isClosed()) {
cursor.close();
}
cursor = null;
}
}
/*
You'll have to handle onChange() yourself since I removed the DaoObserver interface
for it to be compatible with OrmLite 4.48
*/
public void onChange() {
onContentChanged();
}
public PreparedQuery<T> getQuery() {
return query;
}
public void setQuery(PreparedQuery<T> mQuery) {
this.query = mQuery;
}
}
package com.example.ormlite.cursor;
import android.app.Activity;
import android.app.LoaderManager;
import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;
import com.example.ormlite.cursor.R;
import com.example.ormlite.cursor.OrmLiteCursorLoader;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.PreparedQuery;
import java.sql.SQLException;
/**
* Created by andrei on 30/01/15.
*/
public class UsageActivity extends Activity implements LoaderManager.LoaderCallbacks<Cursor> {
public static final int CURSOR_LOADER_ID = "CURSOR_LOADER_ID".hashCode();
private Dao<Long, DeviceModel> mDeviceModelDao;
private PreparedQuery<Long> mYourAwesomeQuery;
private DeviceCursorAdapter mDeviceCursorAdapter;
private ListView mDevicesListView;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.your_awesome_activiy_layout);
this.mDevicesListView = (ListView) this.findViewById(R.id.your_awesome_devices_list_view);
this.mDeviceModelDao = ((AwesomeApplication)getApplicationContext()).getDatabaseHelper().getDeviceModelDao();
try {
this.mYourAwesomeQuery = mDeviceModelDao.queryBuilder().selectColumns("name","_id").prepare();
} catch (SQLException e) {
Log.e(this.getClass().getSimpleName(), e.getMessage());
}
this.mDeviceCursorAdapter = new DeviceCursorAdapter(this);
this.mDevicesListView.setAdapter(mDeviceCursorAdapter);
this.getLoaderManager().initLoader(CURSOR_LOADER_ID, null, this);
}
@Override public Loader onCreateLoader(int id, Bundle args) {
return new OrmLiteCursorLoader<>(this, mDeviceModelDao, mYourAwesomeQuery);
}
@Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
this.mDeviceCursorAdapter.swapCursor(data);
}
@Override public void onLoaderReset(Loader loader) {
this.mDeviceCursorAdapter.swapCursor(null);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment