Fields Summary |
---|
public static final int | ITEM_VIEW_TYPE_IGNOREThe 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_FOOTERThe item view type returned by {@link Adapter#getItemViewType(int)} when
the item is a header or footer. |
int | mFirstPositionThe position of the first child displayed |
int | mSpecificTopThe offset in pixels from the top of the AdapterView to the top
of the view to select during the next layout. |
int | mSyncPositionPosition from which to start looking for mSyncRowId |
long | mSyncRowIdRow id to look for when data has changed |
long | mSyncHeightHeight of the view when mSyncPosition and mSyncRowId where set |
boolean | mNeedSyncTrue if we need to sync to mSyncRowId |
int | mSyncModeIndicates whether to sync based on the selection or position. Possible
values are {@link #SYNC_SELECTED_POSITION} or
{@link #SYNC_FIRST_POSITION}. |
private int | mLayoutHeightOur height after the last layout |
static final int | SYNC_SELECTED_POSITIONSync based on the selected child |
static final int | SYNC_FIRST_POSITIONSync based on the first child displayed |
static final int | SYNC_MAX_DURATION_MILLISMaximum amount of time to spend in {@link #findSyncPosition()} |
boolean | mInLayoutIndicates that this view is currently being laid out. |
OnItemSelectedListener | mOnItemSelectedListenerThe listener that receives notifications when an item is selected. |
OnItemClickListener | mOnItemClickListenerThe listener that receives notifications when an item is clicked. |
OnItemLongClickListener | mOnItemLongClickListenerThe listener that receives notifications when an item is long clicked. |
boolean | mDataChangedTrue if the data has changed since the last layout |
int | mNextSelectedPositionThe position within the adapter's data set of the item to select
during the next layout. |
long | mNextSelectedRowIdThe item id of the item to select during the next layout. |
int | mSelectedPositionThe position within the adapter's data set of the currently selected item. |
long | mSelectedRowIdThe item id of the currently selected item. |
private android.view.View | mEmptyViewView to show if there are no items to show. |
int | mItemCountThe number of items in the current adapter. |
int | mOldItemCountThe number of items in the adapter before a data changed event occurred. |
public static final int | INVALID_POSITIONRepresents 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_IDRepresents an empty or invalid row id |
int | mOldSelectedPositionThe last selected position we used when notifying |
long | mOldSelectedRowIdThe id of the last selected position we used when notifying |
private boolean | mDesiredFocusableStateIndicates 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 | mSelectionNotifierLazily-constructed runnable for dispatching selection events. |
private SelectionNotifier | mPendingSelectionNotifierSelection notifier that's waiting for the next layout pass. |
boolean | mBlockLayoutRequestsWhen set to true, calls to requestLayout() will not propagate up the parent hierarchy.
This is used to layout the children during a layout pass. |
Methods Summary |
---|
public void | addView(android.view.View child)This method is not supported and throws an UnsupportedOperationException when called.
throw new UnsupportedOperationException("addView(View) is not supported in AdapterView");
|
public void | addView(android.view.View child, int index)This method is not supported and throws an UnsupportedOperationException when called.
throw new UnsupportedOperationException("addView(View, int) is not supported in AdapterView");
|
public void | addView(android.view.View child, LayoutParams params)This method is not supported and throws an UnsupportedOperationException when called.
throw new UnsupportedOperationException("addView(View, LayoutParams) "
+ "is not supported in AdapterView");
|
public void | addView(android.view.View child, int index, LayoutParams params)This method is not supported and throws an UnsupportedOperationException when called.
throw new UnsupportedOperationException("addView(View, int, LayoutParams) "
+ "is not supported in AdapterView");
|
protected boolean | canAnimate()
return super.canAnimate() && mItemCount > 0;
|
void | checkFocus()
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());
}
|
void | checkSelectionChanged()Called after layout to determine whether the selection position needs to
be updated. Also used to fire any pending selection events.
if ((mSelectedPosition != mOldSelectedPosition) || (mSelectedRowId != mOldSelectedRowId)) {
selectionChanged();
mOldSelectedPosition = mSelectedPosition;
mOldSelectedRowId = mSelectedRowId;
}
// If we have a pending selection notification -- and we won't if we
// just fired one in selectionChanged() -- run it now.
if (mPendingSelectionNotifier != null) {
mPendingSelectionNotifier.run();
}
|
private void | dispatchOnItemSelected()
fireOnSelected();
performAccessibilityActionsOnSelected();
|
public boolean | dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent event)
View selectedView = getSelectedView();
if (selectedView != null && selectedView.getVisibility() == VISIBLE
&& selectedView.dispatchPopulateAccessibilityEvent(event)) {
return true;
}
return false;
|
protected void | dispatchRestoreInstanceState(android.util.SparseArray container)Override to prevent thawing of any views created by the adapter.
dispatchThawSelfOnly(container);
|
protected void | dispatchSaveInstanceState(android.util.SparseArray container)Override to prevent freezing of any views created by the adapter.
dispatchFreezeSelfOnly(container);
|
int | findSyncPosition()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
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 void | fireOnSelected()
if (mOnItemSelectedListener == null) {
return;
}
final int selection = getSelectedItemPosition();
if (selection >= 0) {
View v = getSelectedView();
mOnItemSelectedListener.onItemSelected(this, v, selection,
getAdapter().getItemId(selection));
} else {
mOnItemSelectedListener.onNothingSelected(this);
}
|
public abstract T | getAdapter()Returns the adapter currently associated with this widget.
|
public int | getCount()
return mItemCount;
|
public android.view.View | getEmptyView()When the current adapter is empty, the AdapterView can display a special view
called the empty view. The empty view is used to provide feedback to the user
that no data is available in this AdapterView.
return mEmptyView;
|
public int | getFirstVisiblePosition()Returns the position within the adapter's data set for the first item
displayed on screen.
return mFirstPosition;
|
public java.lang.Object | getItemAtPosition(int position)Gets the data associated with the specified position in the list.
T adapter = getAdapter();
return (adapter == null || position < 0) ? null : adapter.getItem(position);
|
public long | getItemIdAtPosition(int position)
T adapter = getAdapter();
return (adapter == null || position < 0) ? INVALID_ROW_ID : adapter.getItemId(position);
|
public int | getLastVisiblePosition()Returns the position within the adapter's data set for the last item
displayed on screen.
return mFirstPosition + getChildCount() - 1;
|
public final android.widget.AdapterView$OnItemClickListener | getOnItemClickListener()
return mOnItemClickListener;
|
public final android.widget.AdapterView$OnItemLongClickListener | getOnItemLongClickListener()
return mOnItemLongClickListener;
|
public final android.widget.AdapterView$OnItemSelectedListener | getOnItemSelectedListener()
return mOnItemSelectedListener;
|
public int | getPositionForView(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.
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.Object | getSelectedItem()
T adapter = getAdapter();
int selection = getSelectedItemPosition();
if (adapter != null && adapter.getCount() > 0 && selection >= 0) {
return adapter.getItem(selection);
} else {
return null;
}
|
public long | getSelectedItemId()
return mNextSelectedRowId;
|
public int | getSelectedItemPosition()Return the position of the currently selected item within the adapter's data set
return mNextSelectedPosition;
|
public abstract android.view.View | getSelectedView()
|
void | handleDataChanged()
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();
}
notifySubtreeAccessibilityStateChangedIfNeeded();
|
boolean | isInFilterMode()Indicates whether this view is in filter mode. Filter mode can for instance
be enabled by a user when typing on the keyboard.
return false;
|
private boolean | isScrollableForAccessibility()
T adapter = getAdapter();
if (adapter != null) {
final int itemCount = adapter.getCount();
return itemCount > 0
&& (getFirstVisiblePosition() > 0 || getLastVisiblePosition() < itemCount - 1);
}
return false;
|
int | lookForSelectablePosition(int position, boolean lookDown)Find a position that can be selected (i.e., is not a separator).
return position;
|
protected void | onDetachedFromWindow()
super.onDetachedFromWindow();
removeCallbacks(mSelectionNotifier);
|
public void | onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent event)
super.onInitializeAccessibilityEvent(event);
event.setClassName(AdapterView.class.getName());
event.setScrollable(isScrollableForAccessibility());
View selectedView = getSelectedView();
if (selectedView != null) {
event.setEnabled(selectedView.isEnabled());
}
event.setCurrentItemIndex(getSelectedItemPosition());
event.setFromIndex(getFirstVisiblePosition());
event.setToIndex(getLastVisiblePosition());
event.setItemCount(getCount());
|
public void | onInitializeAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo info)
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(AdapterView.class.getName());
info.setScrollable(isScrollableForAccessibility());
View selectedView = getSelectedView();
if (selectedView != null) {
info.setEnabled(selectedView.isEnabled());
}
|
protected void | onLayout(boolean changed, int left, int top, int right, int bottom)
mLayoutHeight = getHeight();
|
public boolean | onRequestSendAccessibilityEvent(android.view.View child, android.view.accessibility.AccessibilityEvent event)
if (super.onRequestSendAccessibilityEvent(child, event)) {
// Add a record for ourselves as well.
AccessibilityEvent record = AccessibilityEvent.obtain();
onInitializeAccessibilityEvent(record);
// Populate with the text of the requesting child.
child.dispatchPopulateAccessibilityEvent(record);
event.appendRecord(record);
return true;
}
return false;
|
private void | performAccessibilityActionsOnSelected()
if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
return;
}
final int position = getSelectedItemPosition();
if (position >= 0) {
// we fire selection events here not in View
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
}
|
public boolean | performItemClick(android.view.View view, int position, long id)Call the OnItemClickListener, if it is defined. Performs all normal
actions associated with clicking: reporting accessibility event, playing
a sound, etc.
if (mOnItemClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
mOnItemClickListener.onItemClick(this, view, position, id);
if (view != null) {
view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
}
return true;
}
return false;
|
void | rememberSyncState()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 void | removeAllViews()This method is not supported and throws an UnsupportedOperationException when called.
throw new UnsupportedOperationException("removeAllViews() is not supported in AdapterView");
|
public void | removeView(android.view.View child)This method is not supported and throws an UnsupportedOperationException when called.
throw new UnsupportedOperationException("removeView(View) is not supported in AdapterView");
|
public void | removeViewAt(int index)This method is not supported and throws an UnsupportedOperationException when called.
throw new UnsupportedOperationException("removeViewAt(int) is not supported in AdapterView");
|
void | selectionChanged()
// We're about to post or run the selection notifier, so we don't need
// a pending notifier.
mPendingSelectionNotifier = null;
if (mOnItemSelectedListener != null
|| AccessibilityManager.getInstance(mContext).isEnabled()) {
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 accommodate
// new layout or invalidate requests.
if (mSelectionNotifier == null) {
mSelectionNotifier = new SelectionNotifier();
} else {
removeCallbacks(mSelectionNotifier);
}
post(mSelectionNotifier);
} else {
dispatchOnItemSelected();
}
}
|
public abstract void | setAdapter(T adapter)Sets the adapter that provides the data and the views to represent the data
in this widget.
|
public void | setEmptyView(android.view.View emptyView)Sets the view to show if the adapter is empty
mEmptyView = emptyView;
// If not explicitly specified this view is important for accessibility.
if (emptyView != null
&& emptyView.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
emptyView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
}
final T adapter = getAdapter();
final boolean empty = ((adapter == null) || adapter.isEmpty());
updateEmptyStatus(empty);
|
public void | setFocusable(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 void | setFocusableInTouchMode(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()));
|
void | setNextSelectedPositionInt(int position)Utility to keep mNextSelectedPosition and mNextSelectedRowId in sync
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 void | setOnClickListener(OnClickListener l)
throw new RuntimeException("Don't call setOnClickListener for an AdapterView. "
+ "You probably want setOnItemClickListener instead");
|
public void | setOnItemClickListener(android.widget.AdapterView$OnItemClickListener listener)Register a callback to be invoked when an item in this AdapterView has
been clicked.
mOnItemClickListener = listener;
|
public void | setOnItemLongClickListener(android.widget.AdapterView$OnItemLongClickListener listener)Register a callback to be invoked when an item in this AdapterView has
been clicked and held
if (!isLongClickable()) {
setLongClickable(true);
}
mOnItemLongClickListener = listener;
|
public void | setOnItemSelectedListener(android.widget.AdapterView$OnItemSelectedListener listener)Register a callback to be invoked when an item in this AdapterView has
been selected.
mOnItemSelectedListener = listener;
|
void | setSelectedPositionInt(int position)Utility to keep mSelectedPosition and mSelectedRowId in sync
mSelectedPosition = position;
mSelectedRowId = getItemIdAtPosition(position);
|
public abstract void | setSelection(int position)Sets the currently selected item. To support accessibility subclasses that
override this method must invoke the overriden super method first.
|
private void | updateEmptyStatus(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);
}
|