summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorAdam Powell <adamp@google.com>2010-12-19 16:12:19 -0800
committerAdam Powell <adamp@google.com>2010-12-19 16:16:43 -0800
commit50f784cf2dc2dea8061153ac3a843f60a9d88781 (patch)
treec70c81d33b2e22d81f47d39ce169df3673d558d2 /core
parent6ecf3d1690789ace1a667093ad6bbdd6cd35bda7 (diff)
downloadframeworks_base-50f784cf2dc2dea8061153ac3a843f60a9d88781.zip
frameworks_base-50f784cf2dc2dea8061153ac3a843f60a9d88781.tar.gz
frameworks_base-50f784cf2dc2dea8061153ac3a843f60a9d88781.tar.bz2
Measure spinner items for sizing the dropdown view.
Only a limited window of items will be measured around the currently selected item. Change-Id: Ie0431948fdd564fa4bbeb82dede9e2abebbaee55
Diffstat (limited to 'core')
-rw-r--r--core/java/android/widget/Spinner.java45
-rw-r--r--core/java/com/android/internal/view/menu/MenuPopupHelper.java6
2 files changed, 51 insertions, 0 deletions
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index b90837c..bdf24e0 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -24,6 +24,7 @@ import android.content.DialogInterface.OnClickListener;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -43,6 +44,9 @@ import android.view.ViewGroup;
public class Spinner extends AbsSpinner implements OnClickListener {
private static final String TAG = "Spinner";
+ // Only measure this many items to get a decent max width.
+ private static final int MAX_ITEMS_MEASURED = 15;
+
/**
* Use a dialog window for selecting spinner options.
*/
@@ -584,6 +588,7 @@ public class Spinner extends AbsSpinner implements OnClickListener {
private CharSequence mHintText;
private TextView mHintView;
private int mHintResource;
+ private int mPopupMaxWidth;
public DropdownPopup(Context context, AttributeSet attrs,
int defStyleRes, int hintResource) {
@@ -591,6 +596,9 @@ public class Spinner extends AbsSpinner implements OnClickListener {
mHintResource = hintResource;
+ final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ mPopupMaxWidth = metrics.widthPixels / 2;
+
setAnchorView(Spinner.this);
setModal(true);
setPromptPosition(POSITION_PROMPT_ABOVE);
@@ -622,9 +630,46 @@ public class Spinner extends AbsSpinner implements OnClickListener {
setPromptView(textView);
mHintView = textView;
}
+ setContentWidth(Math.min(
+ Math.max(measureContentWidth(getAdapter()), Spinner.this.getWidth()),
+ mPopupMaxWidth));
super.show();
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
setSelection(Spinner.this.getSelectedItemPosition());
}
+
+ private int measureContentWidth(SpinnerAdapter adapter) {
+ int width = 0;
+ View itemView = null;
+ int itemType = 0;
+ final int widthMeasureSpec =
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ final int heightMeasureSpec =
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+
+ // Make sure the number of items we'll measure is capped. If it's a huge data set
+ // with wildly varying sizes, oh well.
+ final int start = Math.max(0, getSelectedItemPosition());
+ final int count = Math.min(adapter.getCount(), start + MAX_ITEMS_MEASURED);
+ for (int i = start; i < count; i++) {
+ final int positionType = adapter.getItemViewType(i);
+ if (positionType != itemType) {
+ itemType = positionType;
+ itemView = null;
+ }
+ itemView = adapter.getDropDownView(i, itemView, Spinner.this);
+ if (itemView.getLayoutParams() == null) {
+ itemView.setLayoutParams(generateDefaultLayoutParams());
+ }
+ itemView.measure(widthMeasureSpec, heightMeasureSpec);
+ width = Math.max(width, itemView.getMeasuredWidth());
+ }
+ return width;
+ }
+
+ private ViewGroup.LayoutParams generateDefaultLayoutParams() {
+ return new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT);
+ }
}
}
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index a5fd38e..d78fbbc 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -142,12 +142,18 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
// Menus don't tend to be long, so this is more sane than it looks.
int width = 0;
View itemView = null;
+ int itemType = 0;
final int widthMeasureSpec =
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
final int heightMeasureSpec =
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
final int count = adapter.getCount();
for (int i = 0; i < count; i++) {
+ final int positionType = adapter.getItemViewType(i);
+ if (positionType != itemType) {
+ itemType = positionType;
+ itemView = null;
+ }
itemView = adapter.getView(i, itemView, null);
itemView.measure(widthMeasureSpec, heightMeasureSpec);
width = Math.max(width, itemView.getMeasuredWidth());