Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package android.support.car.ui;
     17 
     18 import android.content.Context;
     19 import android.database.Cursor;
     20 import android.database.DataSetObserver;
     21 import android.provider.BaseColumns;
     22 import android.support.v7.widget.RecyclerView;
     23 
     24 /**
     25  * Adapter that exposes data from a Cursor to a {@link RecyclerView} widget.
     26  * The Cursor must include an Id column or this class will not work.
     27  */
     28 public abstract  class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHolder>
     29         extends RecyclerView.Adapter<VH> {
     30 
     31     protected Context mContext;
     32     protected Cursor mCursor;
     33     protected int mRowIdColumn;
     34 
     35     public CursorRecyclerViewAdapter(Context context, Cursor cursor) {
     36         mContext = context;
     37         mCursor = cursor;
     38         mRowIdColumn = -1;
     39         if (mCursor != null) {
     40             mRowIdColumn = getRowIdColumnIndex(mCursor);
     41             mCursor.registerDataSetObserver(mDataSetObserver);
     42         }
     43     }
     44 
     45     public Cursor getCursor() {
     46         return mCursor;
     47     }
     48 
     49     @Override
     50     public int getItemCount() {
     51         if (mCursor != null) {
     52             return mCursor.getCount();
     53         }
     54         return 0;
     55     }
     56 
     57     @Override
     58     public long getItemId(int position) {
     59         if (mCursor != null && mCursor.moveToPosition(position)) {
     60             return mCursor.getLong(mRowIdColumn);
     61         }
     62         return 0;
     63     }
     64 
     65     public void onBindViewHolder(VH viewHolder, Cursor cursor) {}
     66 
     67     @Override
     68     public void onBindViewHolder(VH viewHolder, int position) {
     69         if (!mCursor.moveToPosition(position)) {
     70             throw new IllegalStateException("can't move cursor to position " + position);
     71         }
     72         onBindViewHolder(viewHolder, mCursor);
     73     }
     74 
     75     /**
     76      * Change the underlying cursor to a new cursor. If there is an existing cursor it will
     77      * be closed.
     78      *
     79      * @param cursor The new cursor to be used.
     80      */
     81     public void changeCursor(Cursor cursor) {
     82         Cursor old = swapCursor(cursor);
     83         if (old != null) {
     84             old.close();
     85         }
     86     }
     87 
     88     /**
     89      * Swap in a new Cursor, returning the old Cursor. Unlike changeCursor(android.database.Cursor),
     90      * the returned old Cursor is not closed.
     91      *
     92      * @param newCursor The new cursor to be used.
     93      */
     94     public Cursor swapCursor(Cursor newCursor) {
     95         if (newCursor == mCursor) {
     96             return null;
     97         }
     98 
     99         Cursor oldCursor = mCursor;
    100         if (oldCursor != null) {
    101             if (mDataSetObserver != null) {
    102                 oldCursor.unregisterDataSetObserver(mDataSetObserver);
    103             }
    104         }
    105 
    106         mCursor = newCursor;
    107         if (mCursor != null) {
    108             if (mDataSetObserver != null) {
    109                 mCursor.registerDataSetObserver(mDataSetObserver);
    110             }
    111             mRowIdColumn = getRowIdColumnIndex(mCursor);
    112             notifyDataSetChanged();
    113         } else {
    114             mRowIdColumn = -1;
    115             notifyDataSetChanged();
    116         }
    117         return oldCursor;
    118     }
    119 
    120     protected int getRowIdColumnIndex(Cursor cursor) {
    121         return cursor.getColumnIndex(BaseColumns._ID);
    122     }
    123 
    124     protected DataSetObserver mDataSetObserver = new DataSetObserver() {
    125         @Override
    126         public void onChanged() {
    127             super.onChanged();
    128             notifyDataSetChanged();
    129         }
    130 
    131         @Override
    132         public void onInvalidated() {
    133             super.onInvalidated();
    134             mCursor = null;
    135             notifyDataSetChanged();
    136         }
    137     };
    138 }
    139