Skip to content

Instantly share code, notes, and snippets.

@tsohr
Forked from dnlbauer/CursorRecyclerViewAdapter
Last active May 17, 2016 07:33
Show Gist options
  • Save tsohr/a7c5efb14097b68ce84d211deb5ac498 to your computer and use it in GitHub Desktop.
Save tsohr/a7c5efb14097b68ce84d211deb5ac498 to your computer and use it in GitHub Desktop.
Ormlite+RecyclerView
package synctest.insight.romax.com.synctest;
/*
* Copyright (C) 2014 skyfish.jy@gmail.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import android.database.Cursor;
import android.support.v7.widget.RecyclerView;
// Code from https://gist.github.com/skyfishjy/443b7448f59be978bc59
// Fix to remove observers (when using CursorLoaders) by: https://gist.github.com/quanturium/46541c81aae2a916e31d
public abstract class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
private Cursor mCursor;
private boolean mDataValid;
private int mRowIdColumn;
public CursorRecyclerViewAdapter(Cursor cursor) {
mCursor = cursor;
mDataValid = cursor != null;
mRowIdColumn = mDataValid ? mCursor.getColumnIndexOrThrow("_id") : -1;
setHasStableIds(true);
}
public Cursor getCursor() {
return mCursor;
}
@Override
public int getItemCount() {
if (mDataValid && mCursor != null) {
return mCursor.getCount();
} else {
return 0;
}
}
@Override
public long getItemId(int position) {
if (hasStableIds() && mDataValid && mCursor != null) {
if (mCursor.moveToPosition(position)) {
return mCursor.getLong(mRowIdColumn);
} else {
return RecyclerView.NO_ID;
}
} else {
return RecyclerView.NO_ID;
}
}
public Object getItem(int position) {
if (mDataValid && mCursor != null) {
mCursor.moveToPosition(position);
return mCursor;
} else {
return null;
}
}
public abstract void onBindViewHolder(VH viewHolder, Cursor cursor);
@Override
public void onBindViewHolder(VH 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);
}
onBindViewHolder(viewHolder, mCursor);
}
/**
* Change the underlying cursor to a new cursor. If there is an existing cursor it will be
* closed.
*/
public void changeCursor(Cursor cursor) {
Cursor old = swapCursor(cursor);
if (old != null) {
old.close();
}
}
/**
* Swap in a new Cursor, returning the old Cursor. Unlike
* {@link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em>
* closed.
*/
public Cursor swapCursor(Cursor newCursor) {
if (newCursor == mCursor) {
return null;
}
final Cursor oldCursor = mCursor;
mCursor = newCursor;
if (mCursor != null) {
mRowIdColumn = newCursor.getColumnIndexOrThrow("_id");
mDataValid = true;
notifyDataSetChanged();
} else {
mRowIdColumn = -1;
mDataValid = false;
// notify the observers about the lack of a data set
notifyItemRangeRemoved(0, getItemCount());
}
return oldCursor;
}
}
Cursor cursor = null;
PreparedQuery<Inspection> preparedQuery = null;
SQLiteDatabase db = MainActivity.getDatabase(context);
if (db != null) {
try {
RuntimeExceptionDao<Inspection, Long> dao;
dao = RuntimeExceptionDao.createDao(new AndroidConnectionSource(db), Inspection.class);
preparedQuery = dao.queryBuilder().prepare();
AndroidDatabaseResults results = (AndroidDatabaseResults) dao.iterator(preparedQuery).getRawResults();
cursor = results.getRawCursor();
recyclerView.setAdapter(new MyInspectionRecyclerViewAdapter(cursor, preparedQuery, mListener));
} catch (SQLException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
package synctest.insight.romax.com.synctest;
import android.database.Cursor;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.TextView;
import com.j256.ormlite.stmt.PreparedQuery;
import synctest.insight.romax.com.synctest.Page1Fragment.OnListFragmentInteractionListener;
/**
* {@link RecyclerView.Adapter} that can display a {@link Inspection} and makes a call to the
* specified {@link OnListFragmentInteractionListener}.
* TODO: Replace the implementation with code for your data type.
*/
public class MyInspectionRecyclerViewAdapter extends OrmliteCursorRecyclerViewAdapter<Inspection, MyInspectionRecyclerViewAdapter.ViewHolder> {
private Adapter adapter;
private OnListFragmentInteractionListener mListener = null;
public MyInspectionRecyclerViewAdapter(Cursor cursor, PreparedQuery<Inspection> pq, OnListFragmentInteractionListener mListener) {
super(cursor, pq);
this.mListener = mListener;
}
public void setOnListFragmentInteractionListener(OnListFragmentInteractionListener listener) {
this.mListener = listener;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fragment_inspection, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, Inspection inspection) {
holder.mItem = inspection;
holder.mIdView.setText(Long.toString(inspection._id));
holder.mContentView.setText(inspection.report_title);
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != mListener) {
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mListener.onListFragmentInteraction(holder.mItem);
}
}
});
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mIdView;
public final TextView mContentView;
public Inspection mItem;
public ViewHolder(View view) {
super(view);
mView = view;
mIdView = (TextView) view.findViewById(R.id.id);
mContentView = (TextView) view.findViewById(R.id.content);
}
@Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}
package synctest.insight.romax.com.synctest;
// https://gist.github.com/guilhermekrz/504ea775ad3e15932836
import android.database.Cursor;
import android.support.v7.widget.RecyclerView;
import com.j256.ormlite.android.AndroidDatabaseResults;
import com.j256.ormlite.stmt.PreparedQuery;
import java.sql.SQLException;
// Based on https://github.com/j256/ormlite-android/pull/8
public abstract class OrmliteCursorRecyclerViewAdapter<T, VH extends RecyclerView.ViewHolder> extends CursorRecyclerViewAdapter<VH> {
protected PreparedQuery<T> preparedQuery;
public OrmliteCursorRecyclerViewAdapter(Cursor cursor, PreparedQuery<T> preparedQuery){
super(cursor);
this.preparedQuery = preparedQuery;
}
public abstract void onBindViewHolder(VH holder, T t);
public final void onBindViewHolder(VH viewHolder, Cursor cursor){
try {
onBindViewHolder(viewHolder, this.cursorToObject(cursor));
} catch (SQLException e) {
e.printStackTrace();
}
}
public final void changeCursor(Cursor cursor) {
throw new UnsupportedOperationException("Please use OrmLiteCursorAdapter.changeCursor(Cursor,PreparedQuery) instead");
}
public void changeCursor(Cursor cursor, PreparedQuery<T> preparedQuery) {
this.setPreparedQuery(preparedQuery);
super.changeCursor(cursor);
}
public void setPreparedQuery(PreparedQuery<T> preparedQuery) {
this.preparedQuery = preparedQuery;
}
public T getTypedItem(int position) {
try {
return this.cursorToObject((Cursor)getItem(position));
} catch (SQLException var3) {
throw new RuntimeException(var3);
}
}
protected T cursorToObject(Cursor cursor) throws SQLException {
return this.preparedQuery.mapRow(new AndroidDatabaseResults(cursor, null));
}
}
@tsohr
Copy link
Author

tsohr commented May 17, 2016

I'd like to have new constructor with a cursor and a preparedQuery, rather than just context, null. cursorToObject() needs to have preparedQuery anyway..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment