Fixes for HeaderViewListAdapter.
Null header and footer, as used by CTS tests, were no longer supported.
Added a static empty list to avoid repetitive null tests in that case.
Fixed getItem/getItemId/getView to handle corner cases.
Changed ListAdapter isEnabled documentation for invalid positions.
http://b/issue?id=2527753
Change-Id: I55e5bf21cb0673d906caa7c669987a6ae869d90f
diff --git a/core/java/android/widget/HeaderViewListAdapter.java b/core/java/android/widget/HeaderViewListAdapter.java
index 981996a..ca97987 100644
--- a/core/java/android/widget/HeaderViewListAdapter.java
+++ b/core/java/android/widget/HeaderViewListAdapter.java
@@ -28,7 +28,6 @@
* associated data objects.
*<p>This is intended as a base class; you will probably not need to
* use this class directly in your own code.
- *
*/
public class HeaderViewListAdapter implements WrapperListAdapter, Filterable {
@@ -130,43 +129,53 @@
}
public boolean isEnabled(int position) {
+ // Header (negative positions will throw an ArrayIndexOutOfBoundsException)
int numHeaders = getHeadersCount();
- if (mAdapter != null && position >= numHeaders) {
- int adjPosition = position - numHeaders;
- int adapterCount = mAdapter.getCount();
- if (adjPosition >= adapterCount) {
- return mFooterViewInfos.get(adjPosition - adapterCount).isSelectable;
- } else {
- return mAdapter.isEnabled(adjPosition);
- }
- } else if (position < numHeaders) {
+ if (position < numHeaders) {
return mHeaderViewInfos.get(position).isSelectable;
}
- return true;
+
+ // Adapter
+ final int adjPosition = position - numHeaders;
+ int adapterCount = 0;
+ if (mAdapter != null) {
+ adapterCount = mAdapter.getCount();
+ if (adjPosition < adapterCount) {
+ return mAdapter.isEnabled(adjPosition);
+ }
+ }
+
+ // Footer (off-limits positions will throw an ArrayIndexOutOfBoundsException)
+ return mFooterViewInfos.get(adjPosition - adapterCount).isSelectable;
}
public Object getItem(int position) {
+ // Header (negative positions will throw an ArrayIndexOutOfBoundsException)
int numHeaders = getHeadersCount();
- if (mAdapter != null && position >= numHeaders) {
- int adjPosition = position - numHeaders;
- int adapterCount = mAdapter.getCount();
- if (adjPosition >= adapterCount) {
- return mFooterViewInfos.get(adjPosition - adapterCount).data;
- } else {
- return mAdapter.getItem(adjPosition);
- }
- } else if (position < numHeaders) {
+ if (position < numHeaders) {
return mHeaderViewInfos.get(position).data;
}
- return null;
+
+ // Adapter
+ final int adjPosition = position - numHeaders;
+ int adapterCount = 0;
+ if (mAdapter != null) {
+ adapterCount = mAdapter.getCount();
+ if (adjPosition < adapterCount) {
+ return mAdapter.getItem(adjPosition);
+ }
+ }
+
+ // Footer (off-limits positions will throw an ArrayIndexOutOfBoundsException)
+ return mFooterViewInfos.get(adjPosition - adapterCount).data;
}
public long getItemId(int position) {
int numHeaders = getHeadersCount();
if (mAdapter != null && position >= numHeaders) {
int adjPosition = position - numHeaders;
- int adapterCnt = mAdapter.getCount();
- if (adjPosition < adapterCnt) {
+ int adapterCount = mAdapter.getCount();
+ if (adjPosition < adapterCount) {
return mAdapter.getItemId(adjPosition);
}
}
@@ -181,19 +190,24 @@
}
public View getView(int position, View convertView, ViewGroup parent) {
+ // Header (negative positions will throw an ArrayIndexOutOfBoundsException)
int numHeaders = getHeadersCount();
- if (mAdapter != null && position >= numHeaders) {
- int adjPosition = position - numHeaders;
- int adapterCount = mAdapter.getCount();
- if (adjPosition >= adapterCount) {
- return mFooterViewInfos.get(adjPosition - adapterCount).view;
- } else {
- return mAdapter.getView(adjPosition, convertView, parent);
- }
- } else if (position < numHeaders) {
+ if (position < numHeaders) {
return mHeaderViewInfos.get(position).view;
}
- return null;
+
+ // Adapter
+ final int adjPosition = position - numHeaders;
+ int adapterCount = 0;
+ if (mAdapter != null) {
+ adapterCount = mAdapter.getCount();
+ if (adjPosition < adapterCount) {
+ return mAdapter.getView(adjPosition, convertView, parent);
+ }
+ }
+
+ // Footer (off-limits positions will throw an ArrayIndexOutOfBoundsException)
+ return mFooterViewInfos.get(adjPosition - adapterCount).view;
}
public int getItemViewType(int position) {
diff --git a/core/java/android/widget/ListAdapter.java b/core/java/android/widget/ListAdapter.java
index a035145..0fd2e70 100644
--- a/core/java/android/widget/ListAdapter.java
+++ b/core/java/android/widget/ListAdapter.java
@@ -36,6 +36,9 @@
/**
* Returns true if the item at the specified position is not a separator.
* (A separator is a non-selectable, non-clickable item).
+ *
+ * The result is unspecified if position is invalid. An {@link ArrayIndexOutOfBoundsException}
+ * should be thrown in that case for fast failure.
*
* @param position Index of the item
* @return True if the item is not a separator