Skip to content

Instantly share code, notes, and snippets.

@SelvinPL
Last active October 7, 2015 12:51
Show Gist options
  • Select an option

  • Save SelvinPL/9175c8edbdab69a63923 to your computer and use it in GitHub Desktop.

Select an option

Save SelvinPL/9175c8edbdab69a63923 to your computer and use it in GitHub Desktop.
import android.content.Context;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(android.R.id.content, new SimpleListFragment()).commit();
}
}
public static class SimpleListFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
final static String SELECTED_ITEM = "SELECTED_ITEM";
private final static String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER};
private final static String orderBy = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME;
private final static Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
private final static String[] whereArgs = null;
//private final static String[] projection = new String[]{"_id", "address", "body"};
//private final static String orderBy = "address";
//private final static Uri uri = Uri.parse("content://sms/inbox");
//private final static String[] whereArgs = null;
//private final static String where = null;
// private final static String[] projection = new String[]{MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DURATION};
// private final static String orderBy = MediaStore.Audio.AudioColumns.ARTIST;
// private final static Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
// private final static String[] whereArgs = null;
// private final static String where = null;
private final static String where = null;
MyListCursorAdapter adapter;
RecyclerView recyclerView;
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(SELECTED_ITEM, adapter.mSelectedItem);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
adapter.mSelectedItem = savedInstanceState.getInt(SELECTED_ITEM, -1);
recyclerView.getLayoutManager().scrollToPosition(adapter.mSelectedItem);
}
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
adapter = new MyListCursorAdapter(getActivity(), null);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
recyclerView = new RecyclerView(getActivity());
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(adapter);
return recyclerView;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().getSupportLoaderManager().initLoader(0, null, this);
}
@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
return new CursorLoader(getActivity(), uri, projection, where, whereArgs, orderBy);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
adapter.swapCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
}
//from https://gist.github.com/skyfishjy/443b7448f59be978bc59
public static abstract class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
private Context mContext;
private Cursor mCursor;
private boolean mDataValid;
private int mRowIdColumn;
private DataSetObserver mDataSetObserver;
public CursorRecyclerViewAdapter(Context context, Cursor cursor) {
mContext = context;
mCursor = cursor;
mDataValid = cursor != null;
mRowIdColumn = mDataValid ? mCursor.getColumnIndex("_id") : -1;
mDataSetObserver = new NotifyingDataSetObserver();
if (mCursor != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
}
public Cursor getCursor() {
return mCursor;
}
@Override
public int getItemCount() {
if (mDataValid && mCursor != null) {
return mCursor.getCount();
}
return 0;
}
@Override
public long getItemId(int position) {
if (mDataValid && mCursor != null && mCursor.moveToPosition(position)) {
return mCursor.getLong(mRowIdColumn);
}
return 0;
}
@Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(true);
}
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;
if (oldCursor != null && mDataSetObserver != null) {
oldCursor.unregisterDataSetObserver(mDataSetObserver);
}
mCursor = newCursor;
if (mCursor != null) {
if (mDataSetObserver != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
mRowIdColumn = newCursor.getColumnIndexOrThrow("_id");
mDataValid = true;
notifyDataSetChanged();
} else {
mRowIdColumn = -1;
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
return oldCursor;
}
private class NotifyingDataSetObserver extends DataSetObserver {
@Override
public void onChanged() {
super.onChanged();
mDataValid = true;
notifyDataSetChanged();
}
@Override
public void onInvalidated() {
super.onInvalidated();
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
}
}
public static class MyListCursorAdapter extends CursorRecyclerViewAdapter<MyListCursorAdapter.ViewHolder> {
public int mSelectedItem = -1;
public MyListCursorAdapter(Context context, Cursor cursor) {
super(context, cursor);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_2, parent, false);
final ViewHolder vh = new ViewHolder(itemView);
vh.mText1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final int old = mSelectedItem;
mSelectedItem = vh.getAdapterPosition();
notifyItemChanged(old);
notifyItemChanged(mSelectedItem);
}
});
return vh;
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, Cursor cursor) {
if (viewHolder.getAdapterPosition() == mSelectedItem)
viewHolder.mText1.setBackgroundColor(Color.RED);
else
viewHolder.mText1.setBackgroundColor(Color.WHITE);
viewHolder.mText1.setText(cursor.getString(1));
viewHolder.mText2.setText(cursor.getString(2));
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public final TextView mText1;
public final TextView mText2;
public ViewHolder(View view) {
super(view);
mText1 = (TextView) view.findViewById(android.R.id.text1);
mText2 = (TextView) view.findViewById(android.R.id.text2);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment