FileDocCategorySizeDatePackage
CompositeCursorAdapter.javaAPI DocAndroid 5.1 API16402Thu Mar 12 22:22:48 GMT 2015com.android.common.widget

CompositeCursorAdapter

public abstract class CompositeCursorAdapter extends android.widget.BaseAdapter
A general purpose adapter that is composed of multiple cursors. It just appends them in the order they are added.

Fields Summary
private static final int
INITIAL_CAPACITY
private final android.content.Context
mContext
private ArrayList
mPartitions
private int
mCount
private boolean
mCacheValid
private boolean
mNotificationsEnabled
private boolean
mNotificationNeeded
Constructors Summary
public CompositeCursorAdapter(android.content.Context context)


       
        this(context, INITIAL_CAPACITY);
    
public CompositeCursorAdapter(android.content.Context context, int initialCapacity)

        mContext = context;
        mPartitions = new ArrayList<Partition>();
    
Methods Summary
public voidaddPartition(boolean showIfEmpty, boolean hasHeader)
Registers a partition. The cursor for that partition can be set later. Partitions should be added in the order they are supposed to appear in the list.

        addPartition(new Partition(showIfEmpty, hasHeader));
    
public voidaddPartition(com.android.common.widget.CompositeCursorAdapter$Partition partition)

        mPartitions.add(partition);
        invalidate();
        notifyDataSetChanged();
    
public voidaddPartition(int location, com.android.common.widget.CompositeCursorAdapter$Partition partition)

        mPartitions.add(location, partition);
        invalidate();
        notifyDataSetChanged();
    
public booleanareAllItemsEnabled()
Returns false if any partition has a header.

        for (Partition mPartition : mPartitions) {
            if (mPartition.hasHeader) {
                return false;
            }
        }
        return true;
    
protected voidbindHeaderView(android.view.View view, int partition, android.database.Cursor cursor)
Binds the header view for the specified partition.

    
protected abstract voidbindView(android.view.View v, int partition, android.database.Cursor cursor, int position)
Binds an item view for the specified partition and position. Position corresponds directly to the current cursor position.

public voidchangeCursor(int partition, android.database.Cursor cursor)
Changes the cursor for an individual partition.

        Cursor prevCursor = mPartitions.get(partition).cursor;
        if (prevCursor != cursor) {
            if (prevCursor != null && !prevCursor.isClosed()) {
                prevCursor.close();
            }
            mPartitions.get(partition).cursor = cursor;
            if (cursor != null) {
                mPartitions.get(partition).idColumnIndex = cursor.getColumnIndex("_id");
            }
            invalidate();
            notifyDataSetChanged();
        }
    
public voidclearPartitions()
Removes cursors for all partitions.

        for (Partition partition : mPartitions) {
            partition.cursor = null;
        }
        invalidate();
        notifyDataSetChanged();
    
public voidclose()
Closes all cursors and removes all partitions.

        for (Partition partition : mPartitions) {
            Cursor cursor = partition.cursor;
            if (cursor != null && !cursor.isClosed()) {
                cursor.close();
            }
        }
        mPartitions.clear();
        invalidate();
        notifyDataSetChanged();
    
protected voidensureCacheValid()

        if (mCacheValid) {
            return;
        }

        mCount = 0;
        for (Partition partition : mPartitions) {
            Cursor cursor = partition.cursor;
            int count;
            if (cursor == null || cursor.isClosed()) {
                count = 0;
            } else {
                count = cursor.getCount();
            }
            if (partition.hasHeader) {
                if (count != 0 || partition.showIfEmpty) {
                    count++;
                }
            }
            partition.count = count;
            mCount += count;
        }

        mCacheValid = true;
    
public android.content.ContextgetContext()

        return mContext;
    
public intgetCount()
Returns the total number of list items in all partitions.

        ensureCacheValid();
        return mCount;
    
public android.database.CursorgetCursor(int partition)
Returns the cursor for the given partition

        return mPartitions.get(partition).cursor;
    
protected android.view.ViewgetHeaderView(int partition, android.database.Cursor cursor, android.view.View convertView, android.view.ViewGroup parent)
Returns the header view for the specified partition, creating one if needed.

        View view = convertView != null
                ? convertView
                : newHeaderView(mContext, partition, cursor, parent);
        bindHeaderView(view, partition, cursor);
        return view;
    
public java.lang.ObjectgetItem(int position)
Returns a pre-positioned cursor for the specified list position.

        ensureCacheValid();
        int start = 0;
        for (Partition mPartition : mPartitions) {
            int end = start + mPartition.count;
            if (position >= start && position < end) {
                int offset = position - start;
                if (mPartition.hasHeader) {
                    offset--;
                }
                if (offset == -1) {
                    return null;
                }
                Cursor cursor = mPartition.cursor;
                if (cursor == null || cursor.isClosed() || !cursor.moveToPosition(offset)) {
                    return null;
                }
                return cursor;
            }
            start = end;
        }

        return null;
    
public longgetItemId(int position)
Returns the item ID for the specified list position.

        ensureCacheValid();
        int start = 0;
        for (Partition mPartition : mPartitions) {
            int end = start + mPartition.count;
            if (position >= start && position < end) {
                int offset = position - start;
                if (mPartition.hasHeader) {
                    offset--;
                }
                if (offset == -1) {
                    return 0;
                }
                if (mPartition.idColumnIndex == -1) {
                    return 0;
                }

                Cursor cursor = mPartition.cursor;
                if (cursor == null || cursor.isClosed() || !cursor.moveToPosition(offset)) {
                    return 0;
                }
                return cursor.getLong(mPartition.idColumnIndex);
            }
            start = end;
        }

        return 0;
    
protected intgetItemViewType(int partition, int position)
Returns the view type for the list item at the specified position in the specified partition.

        return 1;
    
public intgetItemViewType(int position)

        ensureCacheValid();
        int start = 0;
        for (int i = 0, n = mPartitions.size(); i < n; i++) {
            int end = start  + mPartitions.get(i).count;
            if (position >= start && position < end) {
                int offset = position - start;
                if (mPartitions.get(i).hasHeader) {
                    offset--;
                }
                if (offset == -1) {
                    return IGNORE_ITEM_VIEW_TYPE;
                } else {
                    return getItemViewType(i, offset);
                }
            }
            start = end;
        }

        throw new ArrayIndexOutOfBoundsException(position);
    
public intgetItemViewTypeCount()
Returns the overall number of item view types across all partitions. An implementation of this method needs to ensure that the returned count is consistent with the values returned by {@link #getItemViewType(int,int)}.

        return 1;
    
public intgetOffsetInPartition(int position)
Given a list position, return the offset of the corresponding item in its partition. The header, if any, will have offset -1.

        ensureCacheValid();
        int start = 0;
        for (Partition partition : mPartitions) {
            int end = start + partition.count;
            if (position >= start && position < end) {
                int offset = position - start;
                if (partition.hasHeader) {
                    offset--;
                }
                return offset;
            }
            start = end;
        }
        return -1;
    
public com.android.common.widget.CompositeCursorAdapter$PartitiongetPartition(int partitionIndex)

        return mPartitions.get(partitionIndex);
    
public intgetPartitionCount()

        return mPartitions.size();
    
public intgetPartitionForPosition(int position)
Given a list position, returns the index of the corresponding partition.

        ensureCacheValid();
        int start = 0;
        for (int i = 0, n = mPartitions.size(); i < n; i++) {
            int end = start + mPartitions.get(i).count;
            if (position >= start && position < end) {
                return i;
            }
            start = end;
        }
        return -1;
    
public intgetPositionForPartition(int partition)
Returns the first list position for the specified partition.

        ensureCacheValid();
        int position = 0;
        for (int i = 0; i < partition; i++) {
            position += mPartitions.get(i).count;
        }
        return position;
    
public android.view.ViewgetView(int position, android.view.View convertView, android.view.ViewGroup parent)

        ensureCacheValid();
        int start = 0;
        for (int i = 0, n = mPartitions.size(); i < n; i++) {
            int end = start + mPartitions.get(i).count;
            if (position >= start && position < end) {
                int offset = position - start;
                if (mPartitions.get(i).hasHeader) {
                    offset--;
                }
                View view;
                if (offset == -1) {
                    view = getHeaderView(i, mPartitions.get(i).cursor, convertView, parent);
                } else {
                    if (!mPartitions.get(i).cursor.moveToPosition(offset)) {
                        throw new IllegalStateException("Couldn't move cursor to position "
                                + offset);
                    }
                    view = getView(i, mPartitions.get(i).cursor, offset, convertView, parent);
                }
                if (view == null) {
                    throw new NullPointerException("View should not be null, partition: " + i
                            + " position: " + offset);
                }
                return view;
            }
            start = end;
        }

        throw new ArrayIndexOutOfBoundsException(position);
    
protected android.view.ViewgetView(int partition, android.database.Cursor cursor, int position, android.view.View convertView, android.view.ViewGroup parent)
Returns an item view for the specified partition, creating one if needed.

        View view;
        if (convertView != null) {
            view = convertView;
        } else {
            view = newView(mContext, partition, cursor, position, parent);
        }
        bindView(view, partition, cursor, position);
        return view;
    
public intgetViewTypeCount()

        return getItemViewTypeCount() + 1;
    
public booleanhasHeader(int partition)
Returns true if the specified partition was configured to have a header.

        return mPartitions.get(partition).hasHeader;
    
protected voidinvalidate()

        mCacheValid = false;
    
public booleanisEnabled(int position)
Returns true for all items except headers.

        ensureCacheValid();
        int start = 0;
        for (int i = 0, n = mPartitions.size(); i < n; i++) {
            int end = start + mPartitions.get(i).count;
            if (position >= start && position < end) {
                int offset = position - start;
                if (mPartitions.get(i).hasHeader && offset == 0) {
                    return false;
                } else {
                    return isEnabled(i, offset);
                }
            }
            start = end;
        }

        return false;
    
protected booleanisEnabled(int partition, int position)
Returns true if the item at the specified offset of the specified partition is selectable and clickable.

        return true;
    
public booleanisPartitionEmpty(int partition)
Returns true if the specified partition has no cursor or an empty cursor.

        Cursor cursor = mPartitions.get(partition).cursor;
        return cursor == null || cursor.getCount() == 0;
    
protected android.view.ViewnewHeaderView(android.content.Context context, int partition, android.database.Cursor cursor, android.view.ViewGroup parent)
Creates the header view for the specified partition.

        return null;
    
protected abstract android.view.ViewnewView(android.content.Context context, int partition, android.database.Cursor cursor, int position, android.view.ViewGroup parent)
Creates an item view for the specified partition and position. Position corresponds directly to the current cursor position.

public voidnotifyDataSetChanged()

        if (mNotificationsEnabled) {
            mNotificationNeeded = false;
            super.notifyDataSetChanged();
        } else {
            mNotificationNeeded = true;
        }
    
public voidremovePartition(int partitionIndex)

        Cursor cursor = mPartitions.get(partitionIndex).cursor;
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
        }
        mPartitions.remove(partitionIndex);
        invalidate();
        notifyDataSetChanged();
    
public voidsetHasHeader(int partitionIndex, boolean flag)

        mPartitions.get(partitionIndex).hasHeader = flag;
        invalidate();
    
public voidsetNotificationsEnabled(boolean flag)
Enable or disable data change notifications. It may be a good idea to disable notifications before making changes to several partitions at once.

        mNotificationsEnabled = flag;
        if (flag && mNotificationNeeded) {
            notifyDataSetChanged();
        }
    
public voidsetShowIfEmpty(int partitionIndex, boolean flag)

        mPartitions.get(partitionIndex).showIfEmpty = flag;
        invalidate();