FileDocCategorySizeDatePackage
AdapterView.javaAPI DocAndroid 1.5 API35968Wed May 06 22:41:56 BST 2009android.widget

AdapterView

public abstract class AdapterView extends android.view.ViewGroup
An AdapterView is a view whose children are determined by an {@link Adapter}.

See {@link ListView}, {@link GridView}, {@link Spinner} and {@link Gallery} for commonly used subclasses of AdapterView.

Fields Summary
public static final int
ITEM_VIEW_TYPE_IGNORE
The item view type returned by {@link Adapter#getItemViewType(int)} when the adapter does not want the item's view recycled.
public static final int
ITEM_VIEW_TYPE_HEADER_OR_FOOTER
The item view type returned by {@link Adapter#getItemViewType(int)} when the item is a header or footer.
int
mFirstPosition
The position of the first child displayed
int
mSpecificTop
The offset in pixels from the top of the AdapterView to the top of the view to select during the next layout.
int
mSyncPosition
Position from which to start looking for mSyncRowId
long
mSyncRowId
Row id to look for when data has changed
long
mSyncHeight
Height of the view when mSyncPosition and mSyncRowId where set
boolean
mNeedSync
True if we need to sync to mSyncRowId
int
mSyncMode
Indicates whether to sync based on the selection or position. Possible values are {@link #SYNC_SELECTED_POSITION} or {@link #SYNC_FIRST_POSITION}.
private int
mLayoutHeight
Our height after the last layout
static final int
SYNC_SELECTED_POSITION
Sync based on the selected child
static final int
SYNC_FIRST_POSITION
Sync based on the first child displayed
static final int
SYNC_MAX_DURATION_MILLIS
Maximum amount of time to spend in {@link #findSyncPosition()}
boolean
mInLayout
Indicates that this view is currently being laid out.
OnItemSelectedListener
mOnItemSelectedListener
The listener that receives notifications when an item is selected.
OnItemClickListener
mOnItemClickListener
The listener that receives notifications when an item is clicked.
OnItemLongClickListener
mOnItemLongClickListener
The listener that receives notifications when an item is long clicked.
boolean
mDataChanged
True if the data has changed since the last layout
int
mNextSelectedPosition
The position within the adapter's data set of the item to select during the next layout.
long
mNextSelectedRowId
The item id of the item to select during the next layout.
int
mSelectedPosition
The position within the adapter's data set of the currently selected item.
long
mSelectedRowId
The item id of the currently selected item.
android.view.View
mEmptyView
View to show if there are no items to show.
int
mItemCount
The number of items in the current adapter.
int
mOldItemCount
The number of items in the adapter before a data changed event occured.
public static final int
INVALID_POSITION
Represents an invalid position. All valid positions are in the range 0 to 1 less than the number of items in the current adapter.
public static final long
INVALID_ROW_ID
Represents an empty or invalid row id
int
mOldSelectedPosition
The last selected position we used when notifying
long
mOldSelectedRowId
The id of the last selected position we used when notifying
private boolean
mDesiredFocusableState
Indicates what focusable state is requested when calling setFocusable(). In addition to this, this view has other criteria for actually determining the focusable state (such as whether its empty or the text filter is shown).
private boolean
mDesiredFocusableInTouchModeState
private SelectionNotifier
mSelectionNotifier
boolean
mBlockLayoutRequests
When set to true, calls to requestLayout() will not propagate up the parent hierarchy. This is used to layout the children during a layout pass.
Constructors Summary
public AdapterView(android.content.Context context)


       
        super(context);
    
public AdapterView(android.content.Context context, android.util.AttributeSet attrs)

        super(context, attrs);
    
public AdapterView(android.content.Context context, android.util.AttributeSet attrs, int defStyle)

        super(context, attrs, defStyle);
    
Methods Summary
public voidaddView(android.view.View child)
This method is not supported and throws an UnsupportedOperationException when called.

param
child Ignored.
throws
UnsupportedOperationException Every time this method is invoked.

        throw new UnsupportedOperationException("addView(View) is not supported in AdapterView");
    
public voidaddView(android.view.View child, int index)
This method is not supported and throws an UnsupportedOperationException when called.

param
child Ignored.
param
index Ignored.
throws
UnsupportedOperationException Every time this method is invoked.

        throw new UnsupportedOperationException("addView(View, int) is not supported in AdapterView");
    
public voidaddView(android.view.View child, LayoutParams params)
This method is not supported and throws an UnsupportedOperationException when called.

param
child Ignored.
param
params Ignored.
throws
UnsupportedOperationException Every time this method is invoked.

        throw new UnsupportedOperationException("addView(View, LayoutParams) "
                + "is not supported in AdapterView");
    
public voidaddView(android.view.View child, int index, LayoutParams params)
This method is not supported and throws an UnsupportedOperationException when called.

param
child Ignored.
param
index Ignored.
param
params Ignored.
throws
UnsupportedOperationException Every time this method is invoked.

        throw new UnsupportedOperationException("addView(View, int, LayoutParams) "
                + "is not supported in AdapterView");
    
protected booleancanAnimate()

        return super.canAnimate() && mItemCount > 0;
    
voidcheckFocus()

        final T adapter = getAdapter();
        final boolean empty = adapter == null || adapter.getCount() == 0;
        final boolean focusable = !empty || isInFilterMode();
        // The order in which we set focusable in touch mode/focusable may matter
        // for the client, see View.setFocusableInTouchMode() comments for more
        // details
        super.setFocusableInTouchMode(focusable && mDesiredFocusableInTouchModeState);
        super.setFocusable(focusable && mDesiredFocusableState);
        if (mEmptyView != null) {
            updateEmptyStatus((adapter == null) || adapter.isEmpty());
        }
    
voidcheckSelectionChanged()

        if ((mSelectedPosition != mOldSelectedPosition) || (mSelectedRowId != mOldSelectedRowId)) {
            selectionChanged();
            mOldSelectedPosition = mSelectedPosition;
            mOldSelectedRowId = mSelectedRowId;
        }
    
protected voiddispatchRestoreInstanceState(android.util.SparseArray container)
Override to prevent thawing of any views created by the adapter.

        dispatchThawSelfOnly(container);
    
protected voiddispatchSaveInstanceState(android.util.SparseArray container)
Override to prevent freezing of any views created by the adapter.

        dispatchFreezeSelfOnly(container);
    
intfindSyncPosition()
Searches the adapter for a position matching mSyncRowId. The search starts at mSyncPosition and then alternates between moving up and moving down until 1) we find the right position, or 2) we run out of time, or 3) we have looked at every position

return
Position of the row that matches mSyncRowId, or {@link #INVALID_POSITION} if it can't be found

        int count = mItemCount;

        if (count == 0) {
            return INVALID_POSITION;
        }

        long idToMatch = mSyncRowId;
        int seed = mSyncPosition;

        // If there isn't a selection don't hunt for it
        if (idToMatch == INVALID_ROW_ID) {
            return INVALID_POSITION;
        }

        // Pin seed to reasonable values
        seed = Math.max(0, seed);
        seed = Math.min(count - 1, seed);

        long endTime = SystemClock.uptimeMillis() + SYNC_MAX_DURATION_MILLIS;

        long rowId;

        // first position scanned so far
        int first = seed;

        // last position scanned so far
        int last = seed;

        // True if we should move down on the next iteration
        boolean next = false;

        // True when we have looked at the first item in the data
        boolean hitFirst;

        // True when we have looked at the last item in the data
        boolean hitLast;

        // Get the item ID locally (instead of getItemIdAtPosition), so
        // we need the adapter
        T adapter = getAdapter();
        if (adapter == null) {
            return INVALID_POSITION;
        }

        while (SystemClock.uptimeMillis() <= endTime) {
            rowId = adapter.getItemId(seed);
            if (rowId == idToMatch) {
                // Found it!
                return seed;
            }

            hitLast = last == count - 1;
            hitFirst = first == 0;

            if (hitLast && hitFirst) {
                // Looked at everything
                break;
            }

            if (hitFirst || (next && !hitLast)) {
                // Either we hit the top, or we are trying to move down
                last++;
                seed = last;
                // Try going up next time
                next = false;
            } else if (hitLast || (!next && !hitFirst)) {
                // Either we hit the bottom, or we are trying to move up
                first--;
                seed = first;
                // Try going down next time
                next = true;
            }

        }

        return INVALID_POSITION;
    
private voidfireOnSelected()

        if (mOnItemSelectedListener == null)
            return;

        int selection = this.getSelectedItemPosition();
        if (selection >= 0) {
            View v = getSelectedView();
            mOnItemSelectedListener.onItemSelected(this, v, selection,
                    getAdapter().getItemId(selection));
        } else {
            mOnItemSelectedListener.onNothingSelected(this);
        }
    
public abstract TgetAdapter()
Returns the adapter currently associated with this widget.

return
The adapter used to provide this view's content.

public intgetCount()

return
The number of items owned by the Adapter associated with this AdapterView. (This is the number of data items, which may be larger than the number of visible view.)

        return mItemCount;
    
public android.view.ViewgetEmptyView()
When the current adapter is empty, the AdapterView can display a special view call the empty view. The empty view is used to provide feedback to the user that no data is available in this AdapterView.

return
The view to show if the adapter is empty.

        return mEmptyView;
    
public intgetFirstVisiblePosition()
Returns the position within the adapter's data set for the first item displayed on screen.

return
The position within the adapter's data set

        return mFirstPosition;
    
public java.lang.ObjectgetItemAtPosition(int position)
Gets the data associated with the specified position in the list.

param
position Which data to get
return
The data associated with the specified position in the list

        T adapter = getAdapter();
        return (adapter == null || position < 0) ? null : adapter.getItem(position);
    
public longgetItemIdAtPosition(int position)

        T adapter = getAdapter();
        return (adapter == null || position < 0) ? INVALID_ROW_ID : adapter.getItemId(position);
    
public intgetLastVisiblePosition()
Returns the position within the adapter's data set for the last item displayed on screen.

return
The position within the adapter's data set

        return mFirstPosition + getChildCount() - 1;
    
public final android.widget.AdapterView$OnItemClickListenergetOnItemClickListener()

return
The callback to be invoked with an item in this AdapterView has been clicked, or null id no callback has been set.

        return mOnItemClickListener;
    
public final android.widget.AdapterView$OnItemLongClickListenergetOnItemLongClickListener()

return
The callback to be invoked with an item in this AdapterView has been clicked and held, or null id no callback as been set.

        return mOnItemLongClickListener;
    
public final android.widget.AdapterView$OnItemSelectedListenergetOnItemSelectedListener()

        return mOnItemSelectedListener;
    
public intgetPositionForView(android.view.View view)
Get the position within the adapter's data set for the view, where view is a an adapter item or a descendant of an adapter item.

param
view an adapter item, or a descendant of an adapter item. This must be visible in this AdapterView at the time of the call.
return
the position within the adapter's data set of the view, or {@link #INVALID_POSITION} if the view does not correspond to a list item (or it is not currently visible).

        View listItem = view;
        try {
            View v;
            while (!(v = (View) listItem.getParent()).equals(this)) {
                listItem = v;
            }
        } catch (ClassCastException e) {
            // We made it up to the window without find this list view
            return INVALID_POSITION;
        }

        // Search the children for the list item
        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            if (getChildAt(i).equals(listItem)) {
                return mFirstPosition + i;
            }
        }

        // Child not found!
        return INVALID_POSITION;
    
public java.lang.ObjectgetSelectedItem()

return
The data corresponding to the currently selected item, or null if there is nothing selected.

        T adapter = getAdapter();
        int selection = getSelectedItemPosition();
        if (adapter != null && adapter.getCount() > 0 && selection >= 0) {
            return adapter.getItem(selection);
        } else {
            return null;
        }
    
public longgetSelectedItemId()

return
The id corresponding to the currently selected item, or {@link #INVALID_ROW_ID} if nothing is selected.

        return mNextSelectedRowId;
    
public intgetSelectedItemPosition()
Return the position of the currently selected item within the adapter's data set

return
int Position (starting at 0), or {@link #INVALID_POSITION} if there is nothing selected.

        return mNextSelectedPosition;
    
public abstract android.view.ViewgetSelectedView()

return
The view corresponding to the currently selected item, or null if nothing is selected

voidhandleDataChanged()

        final int count = mItemCount;
        boolean found = false;

        if (count > 0) {

            int newPos;

            // Find the row we are supposed to sync to
            if (mNeedSync) {
                // Update this first, since setNextSelectedPositionInt inspects
                // it
                mNeedSync = false;

                // See if we can find a position in the new data with the same
                // id as the old selection
                newPos = findSyncPosition();
                if (newPos >= 0) {
                    // Verify that new selection is selectable
                    int selectablePos = lookForSelectablePosition(newPos, true);
                    if (selectablePos == newPos) {
                        // Same row id is selected
                        setNextSelectedPositionInt(newPos);
                        found = true;
                    }
                }
            }
            if (!found) {
                // Try to use the same position if we can't find matching data
                newPos = getSelectedItemPosition();

                // Pin position to the available range
                if (newPos >= count) {
                    newPos = count - 1;
                }
                if (newPos < 0) {
                    newPos = 0;
                }

                // Make sure we select something selectable -- first look down
                int selectablePos = lookForSelectablePosition(newPos, true);
                if (selectablePos < 0) {
                    // Looking down didn't work -- try looking up
                    selectablePos = lookForSelectablePosition(newPos, false);
                }
                if (selectablePos >= 0) {
                    setNextSelectedPositionInt(selectablePos);
                    checkSelectionChanged();
                    found = true;
                }
            }
        }
        if (!found) {
            // Nothing is selected
            mSelectedPosition = INVALID_POSITION;
            mSelectedRowId = INVALID_ROW_ID;
            mNextSelectedPosition = INVALID_POSITION;
            mNextSelectedRowId = INVALID_ROW_ID;
            mNeedSync = false;
            checkSelectionChanged();
        }
    
booleanisInFilterMode()
Indicates whether this view is in filter mode. Filter mode can for instance be enabled by a user when typing on the keyboard.

return
True if the view is in filter mode, false otherwise.

        return false;
    
intlookForSelectablePosition(int position, boolean lookDown)
Find a position that can be selected (i.e., is not a separator).

param
position The starting position to look at.
param
lookDown Whether to look down for other positions.
return
The next selectable position starting at position and then searching either up or down. Returns {@link #INVALID_POSITION} if nothing can be found.

        return position;
    
protected voidonLayout(boolean changed, int left, int top, int right, int bottom)

        mLayoutHeight = getHeight();
    
public booleanperformItemClick(android.view.View view, int position, long id)
Call the OnItemClickListener, if it is defined.

param
view The view within the AdapterView that was clicked.
param
position The position of the view in the adapter.
param
id The row id of the item that was clicked.
return
True if there was an assigned OnItemClickListener that was called, false otherwise is returned.

        if (mOnItemClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            mOnItemClickListener.onItemClick(this, view, position, id);
            return true;
        }

        return false;
    
voidrememberSyncState()
Remember enough information to restore the screen state when the data has changed.

        if (getChildCount() > 0) {
            mNeedSync = true;
            mSyncHeight = mLayoutHeight;
            if (mSelectedPosition >= 0) {
                // Sync the selection state
                View v = getChildAt(mSelectedPosition - mFirstPosition);
                mSyncRowId = mNextSelectedRowId;
                mSyncPosition = mNextSelectedPosition;
                if (v != null) {
                    mSpecificTop = v.getTop();
                }
                mSyncMode = SYNC_SELECTED_POSITION;
            } else {
                // Sync the based on the offset of the first view
                View v = getChildAt(0);
                T adapter = getAdapter();
                if (mFirstPosition >= 0 && mFirstPosition < adapter.getCount()) {
                    mSyncRowId = adapter.getItemId(mFirstPosition);
                } else {
                    mSyncRowId = NO_ID;
                }
                mSyncPosition = mFirstPosition;
                if (v != null) {
                    mSpecificTop = v.getTop();
                }
                mSyncMode = SYNC_FIRST_POSITION;
            }
        }
    
public voidremoveAllViews()
This method is not supported and throws an UnsupportedOperationException when called.

throws
UnsupportedOperationException Every time this method is invoked.

        throw new UnsupportedOperationException("removeAllViews() is not supported in AdapterView");
    
public voidremoveView(android.view.View child)
This method is not supported and throws an UnsupportedOperationException when called.

param
child Ignored.
throws
UnsupportedOperationException Every time this method is invoked.

        throw new UnsupportedOperationException("removeView(View) is not supported in AdapterView");
    
public voidremoveViewAt(int index)
This method is not supported and throws an UnsupportedOperationException when called.

param
index Ignored.
throws
UnsupportedOperationException Every time this method is invoked.

        throw new UnsupportedOperationException("removeViewAt(int) is not supported in AdapterView");
    
voidselectionChanged()

        if (mOnItemSelectedListener != null) {
            if (mInLayout || mBlockLayoutRequests) {
                // If we are in a layout traversal, defer notification
                // by posting. This ensures that the view tree is
                // in a consistent state and is able to accomodate
                // new layout or invalidate requests.
                if (mSelectionNotifier == null) {
                    mSelectionNotifier = new SelectionNotifier();
                }
                mSelectionNotifier.post(mSelectionNotifier);
            } else {
                fireOnSelected();
            }
        }
    
public abstract voidsetAdapter(T adapter)
Sets the adapter that provides the data and the views to represent the data in this widget.

param
adapter The adapter to use to create this view's content.

public voidsetEmptyView(android.view.View emptyView)
Sets the view to show if the adapter is empty

        mEmptyView = emptyView;

        final T adapter = getAdapter();
        final boolean empty = ((adapter == null) || adapter.isEmpty());
        updateEmptyStatus(empty);
    
public voidsetFocusable(boolean focusable)

        final T adapter = getAdapter();
        final boolean empty = adapter == null || adapter.getCount() == 0;

        mDesiredFocusableState = focusable;
        if (!focusable) {
            mDesiredFocusableInTouchModeState = false;
        }

        super.setFocusable(focusable && (!empty || isInFilterMode()));
    
public voidsetFocusableInTouchMode(boolean focusable)

        final T adapter = getAdapter();
        final boolean empty = adapter == null || adapter.getCount() == 0;

        mDesiredFocusableInTouchModeState = focusable;
        if (focusable) {
            mDesiredFocusableState = true;
        }

        super.setFocusableInTouchMode(focusable && (!empty || isInFilterMode()));
    
voidsetNextSelectedPositionInt(int position)
Utility to keep mNextSelectedPosition and mNextSelectedRowId in sync

param
position Intended value for mSelectedPosition the next time we go through layout

        mNextSelectedPosition = position;
        mNextSelectedRowId = getItemIdAtPosition(position);
        // If we are trying to sync to the selection, update that too
        if (mNeedSync && mSyncMode == SYNC_SELECTED_POSITION && position >= 0) {
            mSyncPosition = position;
            mSyncRowId = mNextSelectedRowId;
        }
    
public voidsetOnClickListener(OnClickListener l)

        throw new RuntimeException("Don't call setOnClickListener for an AdapterView. "
                + "You probably want setOnItemClickListener instead");
    
public voidsetOnItemClickListener(android.widget.AdapterView$OnItemClickListener listener)
Register a callback to be invoked when an item in this AdapterView has been clicked.

param
listener The callback that will be invoked.

        mOnItemClickListener = listener;
    
public voidsetOnItemLongClickListener(android.widget.AdapterView$OnItemLongClickListener listener)
Register a callback to be invoked when an item in this AdapterView has been clicked and held

param
listener The callback that will run

        if (!isLongClickable()) {
            setLongClickable(true);
        }
        mOnItemLongClickListener = listener;
    
public voidsetOnItemSelectedListener(android.widget.AdapterView$OnItemSelectedListener listener)
Register a callback to be invoked when an item in this AdapterView has been selected.

param
listener The callback that will run

        mOnItemSelectedListener = listener;
    
voidsetSelectedPositionInt(int position)
Utility to keep mSelectedPosition and mSelectedRowId in sync

param
position Our current position

        mSelectedPosition = position;
        mSelectedRowId = getItemIdAtPosition(position);
    
public abstract voidsetSelection(int position)
Sets the currently selected item

param
position Index (starting at 0) of the data item to be selected.

private voidupdateEmptyStatus(boolean empty)
Update the status of the list based on the empty parameter. If empty is true and we have an empty view, display it. In all the other cases, make sure that the listview is VISIBLE and that the empty view is GONE (if it's not null).

        if (isInFilterMode()) {
            empty = false;
        }

        if (empty) {
            if (mEmptyView != null) {
                mEmptyView.setVisibility(View.VISIBLE);
                setVisibility(View.GONE);
            } else {
                // If the caller just removed our empty view, make sure the list view is visible
                setVisibility(View.VISIBLE);
            }

            // We are now GONE, so pending layouts will not be dispatched.
            // Force one here to make sure that the state of the list matches
            // the state of the adapter.
            if (mDataChanged) {           
                this.onLayout(false, mLeft, mTop, mRight, mBottom); 
            }
        } else {
            if (mEmptyView != null) mEmptyView.setVisibility(View.GONE);
            setVisibility(View.VISIBLE);
        }