diff options
| -rw-r--r-- | api/current.txt | 1 | ||||
| -rw-r--r-- | api/system-current.txt | 1 | ||||
| -rw-r--r-- | core/java/android/widget/AutoCompleteTextView.java | 175 | ||||
| -rw-r--r-- | core/res/res/values/attrs.xml | 2 |
4 files changed, 146 insertions, 33 deletions
diff --git a/api/current.txt b/api/current.txt index 47b8aeb0a59a..1e4a63cfb204 100644 --- a/api/current.txt +++ b/api/current.txt @@ -39715,6 +39715,7 @@ package android.widget { ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet); ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet, int); ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet, int, int); + ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet, int, int, android.content.res.Resources.Theme); method public void clearListSelection(); method protected java.lang.CharSequence convertSelectionToString(java.lang.Object); method public void dismissDropDown(); diff --git a/api/system-current.txt b/api/system-current.txt index 45a90e0bfde7..e38286981bbc 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -42361,6 +42361,7 @@ package android.widget { ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet); ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet, int); ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet, int, int); + ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet, int, int, android.content.res.Resources.Theme); method public void clearListSelection(); method protected java.lang.CharSequence convertSelectionToString(java.lang.Object); method public void dismissDropDown(); diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index 01767d52780f..7d57cb83f6df 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -18,6 +18,7 @@ package android.widget; import android.annotation.DrawableRes; import android.content.Context; +import android.content.res.Resources.Theme; import android.content.res.TypedArray; import android.database.DataSetObserver; import android.graphics.Rect; @@ -28,10 +29,12 @@ import android.text.TextUtils; import android.text.TextWatcher; import android.util.AttributeSet; import android.util.Log; +import android.view.ContextThemeWrapper; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; import android.view.WindowManager; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.EditorInfo; @@ -94,6 +97,12 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe static final int EXPAND_MAX = 3; + /** Context used to inflate the popup window or dialog. */ + private final Context mPopupContext; + + private final ListPopupWindow mPopup; + private final PassThroughClickListener mPassThroughClickListener; + private CharSequence mHintText; private TextView mHintView; private int mHintResource; @@ -102,7 +111,6 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe private Filter mFilter; private int mThreshold; - private ListPopupWindow mPopup; private int mDropDownAnchorId; private AdapterView.OnItemClickListener mItemClickListener; @@ -122,71 +130,172 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe // Set to false when the list is hidden to prevent asynchronous updates to popup the list again. private boolean mPopupCanBeUpdated = true; - private PassThroughClickListener mPassThroughClickListener; private PopupDataSetObserver mObserver; + /** + * Constructs a new auto-complete text view with the given context's theme. + * + * @param context The Context the view is running in, through which it can + * access the current theme, resources, etc. + */ public AutoCompleteTextView(Context context) { this(context, null); } + /** + * Constructs a new auto-complete text view with the given context's theme + * and the supplied attribute set. + * + * @param context The Context the view is running in, through which it can + * access the current theme, resources, etc. + * @param attrs The attributes of the XML tag that is inflating the view. + */ public AutoCompleteTextView(Context context, AttributeSet attrs) { this(context, attrs, R.attr.autoCompleteTextViewStyle); } + /** + * Constructs a new auto-complete text view with the given context's theme, + * the supplied attribute set, and default style attribute. + * + * @param context The Context the view is running in, through which it can + * access the current theme, resources, etc. + * @param attrs The attributes of the XML tag that is inflating the view. + * @param defStyleAttr An attribute in the current theme that contains a + * reference to a style resource that supplies default + * values for the view. Can be 0 to not look for + * defaults. + */ public AutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); } + /** + * Constructs a new auto-complete text view with the given context's theme, + * the supplied attribute set, and default styles. + * + * @param context The Context the view is running in, through which it can + * access the current theme, resources, etc. + * @param attrs The attributes of the XML tag that is inflating the view. + * @param defStyleAttr An attribute in the current theme that contains a + * reference to a style resource that supplies default + * values for the view. Can be 0 to not look for + * defaults. + * @param defStyleRes A resource identifier of a style resource that + * supplies default values for the view, used only if + * defStyleAttr is 0 or can not be found in the theme. + * Can be 0 to not look for defaults. + */ public AutoCompleteTextView( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); + this(context, attrs, defStyleAttr, defStyleRes, null); + } - mPopup = new ListPopupWindow(context, attrs, defStyleAttr, defStyleRes); - mPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); - mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW); + /** + * Constructs a new auto-complete text view with the given context, the + * supplied attribute set, default styles, and the theme against which the + * completion popup should be inflated. + * + * @param context The context against which the view is inflated, which + * provides access to the current theme, resources, etc. + * @param attrs The attributes of the XML tag that is inflating the view. + * @param defStyleAttr An attribute in the current theme that contains a + * reference to a style resource that supplies default + * values for the view. Can be 0 to not look for + * defaults. + * @param defStyleRes A resource identifier of a style resource that + * supplies default values for the view, used only if + * defStyleAttr is 0 or can not be found in the theme. + * Can be 0 to not look for defaults. + * @param popupTheme The theme against which the completion popup window + * should be inflated. May be {@code null} to use the + * view theme. If set, this will override any value + * specified by + * {@link android.R.styleable#AutoCompleteTextView_popupTheme}. + */ + public AutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes, Theme popupTheme) { + super(context, attrs, defStyleAttr, defStyleRes); final TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.AutoCompleteTextView, defStyleAttr, defStyleRes); - mThreshold = a.getInt(R.styleable.AutoCompleteTextView_completionThreshold, 2); + if (popupTheme != null) { + mPopupContext = new ContextThemeWrapper(context, popupTheme); + } else { + final int popupThemeResId = a.getResourceId( + R.styleable.AutoCompleteTextView_popupTheme, 0); + if (popupThemeResId != 0) { + mPopupContext = new ContextThemeWrapper(context, popupThemeResId); + } else { + mPopupContext = context; + } + } + + // Load attributes used within the popup against the popup context. + final TypedArray pa; + if (mPopupContext != context) { + pa = mPopupContext.obtainStyledAttributes( + attrs, R.styleable.AutoCompleteTextView, defStyleAttr, defStyleRes); + } else { + pa = a; + } - mPopup.setListSelector(a.getDrawable(R.styleable.AutoCompleteTextView_dropDownSelector)); + final Drawable popupListSelector = pa.getDrawable( + R.styleable.AutoCompleteTextView_dropDownSelector); + final int popupWidth = pa.getLayoutDimension( + R.styleable.AutoCompleteTextView_dropDownWidth, LayoutParams.WRAP_CONTENT); + final int popupHeight = pa.getLayoutDimension( + R.styleable.AutoCompleteTextView_dropDownHeight, LayoutParams.WRAP_CONTENT); + final int popupHintLayoutResId = pa.getResourceId( + R.styleable.AutoCompleteTextView_completionHintView, R.layout.simple_dropdown_hint); + final CharSequence popupHintText = pa.getText( + R.styleable.AutoCompleteTextView_completionHint); + + if (pa != a) { + pa.recycle(); + } - // Get the anchor's id now, but the view won't be ready, so wait to actually get the - // view and store it in mDropDownAnchorView lazily in getDropDownAnchorView later. - // Defaults to NO_ID, in which case the getDropDownAnchorView method will simply return - // this TextView, as a default anchoring point. - mDropDownAnchorId = a.getResourceId(R.styleable.AutoCompleteTextView_dropDownAnchor, - View.NO_ID); - - // For dropdown width, the developer can specify a specific width, or MATCH_PARENT - // (for full screen width) or WRAP_CONTENT (to match the width of the anchored view). - mPopup.setWidth(a.getLayoutDimension(R.styleable.AutoCompleteTextView_dropDownWidth, - ViewGroup.LayoutParams.WRAP_CONTENT)); - mPopup.setHeight(a.getLayoutDimension(R.styleable.AutoCompleteTextView_dropDownHeight, - ViewGroup.LayoutParams.WRAP_CONTENT)); - - mHintResource = a.getResourceId(R.styleable.AutoCompleteTextView_completionHintView, - R.layout.simple_dropdown_hint); - + mPopup = new ListPopupWindow(mPopupContext, attrs, defStyleAttr, defStyleRes); + mPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW); + mPopup.setListSelector(popupListSelector); mPopup.setOnItemClickListener(new DropDownItemClickListener()); - setCompletionHint(a.getText(R.styleable.AutoCompleteTextView_completionHint)); + + // For dropdown width, the developer can specify a specific width, or + // MATCH_PARENT (for full screen width), or WRAP_CONTENT (to match the + // width of the anchored view). + mPopup.setWidth(popupWidth); + mPopup.setHeight(popupHeight); + + // Completion hint must be set after specifying hint layout. + mHintResource = popupHintLayoutResId; + setCompletionHint(popupHintText); + + // Get the anchor's id now, but the view won't be ready, so wait to + // actually get the view and store it in mDropDownAnchorView lazily in + // getDropDownAnchorView later. Defaults to NO_ID, in which case the + // getDropDownAnchorView method will simply return this TextView, as a + // default anchoring point. + mDropDownAnchorId = a.getResourceId( + R.styleable.AutoCompleteTextView_dropDownAnchor, View.NO_ID); + + mThreshold = a.getInt(R.styleable.AutoCompleteTextView_completionThreshold, 2); + + a.recycle(); // Always turn on the auto complete input type flag, since it // makes no sense to use this widget without it. int inputType = getInputType(); - if ((inputType&EditorInfo.TYPE_MASK_CLASS) - == EditorInfo.TYPE_CLASS_TEXT) { + if ((inputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) { inputType |= EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE; setRawInputType(inputType); } - a.recycle(); - setFocusable(true); addTextChangedListener(new MyWatcher()); - + mPassThroughClickListener = new PassThroughClickListener(); super.setOnClickListener(mPassThroughClickListener); } @@ -222,8 +331,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe mHintText = hint; if (hint != null) { if (mHintView == null) { - final TextView hintView = (TextView) LayoutInflater.from(getContext()).inflate( - mHintResource, null).findViewById(com.android.internal.R.id.text1); + final TextView hintView = (TextView) LayoutInflater.from(mPopupContext).inflate( + mHintResource, null).findViewById(R.id.text1); hintView.setText(mHintText); mHintView = hintView; mPopup.setPromptView(hintView); diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 99beef891040..f5528f917625 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -4481,6 +4481,8 @@ i <enum name="wrap_content" value="-2" /> </attr> <attr name="inputType" /> + <!-- Theme to use for the completion popup window. --> + <attr name="popupTheme" /> </declare-styleable> <declare-styleable name="PopupWindow"> <!-- The background to use for the popup window. --> |