diff options
Diffstat (limited to 'src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java')
-rw-r--r-- | src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java | 849 |
1 files changed, 0 insertions, 849 deletions
diff --git a/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java b/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java deleted file mode 100644 index 50ba758..0000000 --- a/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java +++ /dev/null @@ -1,849 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.browser.autocomplete; - -import com.android.browser.BrowserSettings; -import com.android.browser.SuggestionsAdapter; -import com.android.browser.SuggestionsAdapter.SuggestItem; -import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher; -import com.android.internal.R; - -import android.content.Context; -import android.content.res.TypedArray; -import android.database.DataSetObserver; -import android.graphics.Rect; -import android.os.Parcelable; -import android.text.Editable; -import android.text.Html; -import android.text.Selection; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.util.Log; -import android.view.AbsSavedState; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.view.inputmethod.CompletionInfo; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; -import android.widget.AdapterView; -import android.widget.EditText; -import android.widget.Filter; -import android.widget.Filterable; -import android.widget.ListAdapter; -import android.widget.ListPopupWindow; -import android.widget.TextView; - - -/** - * This is a stripped down version of the framework AutoCompleteTextView - * class with added support for displaying completions in-place. Note that - * this cannot be implemented as a subclass of the above without making - * substantial changes to it and its descendants. - * - * @see android.widget.AutoCompleteTextView - */ -public class SuggestiveAutoCompleteTextView extends EditText implements Filter.FilterListener { - private static final boolean DEBUG = false; - private static final String TAG = "SuggestiveAutoCompleteTextView"; - - private CharSequence mHintText; - private TextView mHintView; - private int mHintResource; - - private SuggestionsAdapter mAdapter; - private Filter mFilter; - private int mThreshold; - - private ListPopupWindow mPopup; - private int mDropDownAnchorId; - - private AdapterView.OnItemClickListener mItemClickListener; - - private boolean mDropDownDismissedOnCompletion = true; - - private int mLastKeyCode = KeyEvent.KEYCODE_UNKNOWN; - - // Set to true when text is set directly and no filtering shall be performed - private boolean mBlockCompletion; - - // When set, an update in the underlying adapter will update the result list popup. - // 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; - private SuggestedTextController mController; - - public SuggestiveAutoCompleteTextView(Context context) { - this(context, null); - } - - public SuggestiveAutoCompleteTextView(Context context, AttributeSet attrs) { - this(context, attrs, R.attr.autoCompleteTextViewStyle); - } - - public SuggestiveAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - // The completions are always shown in the same color as the hint - // text. - mController = new SuggestedTextController(this, getHintTextColors().getDefaultColor()); - mPopup = new ListPopupWindow(context, attrs, - R.attr.autoCompleteTextViewStyle); - mPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); - mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW); - - TypedArray a = context.obtainStyledAttributes( - attrs, R.styleable.AutoCompleteTextView, defStyle, 0); - - mThreshold = a.getInt( - R.styleable.AutoCompleteTextView_completionThreshold, 2); - - mPopup.setListSelector(a.getDrawable(R.styleable.AutoCompleteTextView_dropDownSelector)); - mPopup.setVerticalOffset((int) - a.getDimension(R.styleable.AutoCompleteTextView_dropDownVerticalOffset, 0.0f)); - mPopup.setHorizontalOffset((int) - a.getDimension(R.styleable.AutoCompleteTextView_dropDownHorizontalOffset, 0.0f)); - - // 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.setOnItemClickListener(new DropDownItemClickListener()); - setCompletionHint(a.getText(R.styleable.AutoCompleteTextView_completionHint)); - - // 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) { - inputType |= EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE; - setRawInputType(inputType); - } - - a.recycle(); - - setFocusable(true); - - mController.addUserTextChangeWatcher(new MyWatcher()); - - mPassThroughClickListener = new PassThroughClickListener(); - super.setOnClickListener(mPassThroughClickListener); - } - - @Override - public void setOnClickListener(OnClickListener listener) { - mPassThroughClickListener.mWrapped = listener; - } - - /** - * Private hook into the on click event, dispatched from {@link PassThroughClickListener} - */ - private void onClickImpl() { - // If the dropdown is showing, bring the keyboard to the front - // when the user touches the text field. - if (isPopupShowing()) { - ensureImeVisible(true); - } - } - - /** - * <p>Sets the optional hint text that is displayed at the bottom of the - * the matching list. This can be used as a cue to the user on how to - * best use the list, or to provide extra information.</p> - * - * @param hint the text to be displayed to the user - * - * @attr ref android.R.styleable#AutoCompleteTextView_completionHint - */ - private void setCompletionHint(CharSequence hint) { - mHintText = hint; - if (hint != null) { - if (mHintView == null) { - final TextView hintView = (TextView) LayoutInflater.from(getContext()).inflate( - mHintResource, null).findViewById(R.id.text1); - hintView.setText(mHintText); - mHintView = hintView; - mPopup.setPromptView(hintView); - } else { - mHintView.setText(hint); - } - } else { - mPopup.setPromptView(null); - mHintView = null; - } - } - - protected int getDropDownWidth() { - return mPopup.getWidth(); - } - - public void setDropDownWidth(int width) { - mPopup.setWidth(width); - } - - protected void setDropDownVerticalOffset(int offset) { - mPopup.setVerticalOffset(offset); - } - - public void setDropDownHorizontalOffset(int offset) { - mPopup.setHorizontalOffset(offset); - } - - protected int getDropDownHorizontalOffset() { - return mPopup.getHorizontalOffset(); - } - - public void setThreshold(int threshold) { - if (threshold <= 0) { - threshold = 1; - } - - mThreshold = threshold; - } - - protected void setOnItemClickListener(AdapterView.OnItemClickListener l) { - mItemClickListener = l; - } - - public void setAdapter(SuggestionsAdapter adapter) { - if (mObserver == null) { - mObserver = new PopupDataSetObserver(); - } else if (mAdapter != null) { - mAdapter.unregisterDataSetObserver(mObserver); - } - mAdapter = adapter; - if (mAdapter != null) { - mFilter = mAdapter.getFilter(); - adapter.registerDataSetObserver(mObserver); - } else { - mFilter = null; - } - - mPopup.setAdapter(mAdapter); - } - - @Override - public boolean onKeyPreIme(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK && isPopupShowing() - && !mPopup.isDropDownAlwaysVisible()) { - // special case for the back key, we do not even try to send it - // to the drop down list but instead, consume it immediately - if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { - KeyEvent.DispatcherState state = getKeyDispatcherState(); - if (state != null) { - state.startTracking(event, this); - } - return true; - } else if (event.getAction() == KeyEvent.ACTION_UP) { - KeyEvent.DispatcherState state = getKeyDispatcherState(); - if (state != null) { - state.handleUpEvent(event); - } - if (event.isTracking() && !event.isCanceled()) { - dismissDropDown(); - return true; - } - } - } - return super.onKeyPreIme(keyCode, event); - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - boolean consumed = mPopup.onKeyUp(keyCode, event); - if (consumed) { - switch (keyCode) { - // if the list accepts the key events and the key event - // was a click, the text view gets the selected item - // from the drop down as its content - case KeyEvent.KEYCODE_ENTER: - case KeyEvent.KEYCODE_DPAD_CENTER: - case KeyEvent.KEYCODE_TAB: - if (event.hasNoModifiers()) { - performCompletion(); - } - return true; - } - } - - if (isPopupShowing() && keyCode == KeyEvent.KEYCODE_TAB && event.hasNoModifiers()) { - performCompletion(); - return true; - } - - return super.onKeyUp(keyCode, event); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (mPopup.onKeyDown(keyCode, event)) { - return true; - } - - if (!isPopupShowing()) { - switch(keyCode) { - case KeyEvent.KEYCODE_DPAD_DOWN: - if (event.hasNoModifiers()) { - performValidation(); - } - } - } - - if (isPopupShowing() && keyCode == KeyEvent.KEYCODE_TAB && event.hasNoModifiers()) { - return true; - } - - mLastKeyCode = keyCode; - boolean handled = super.onKeyDown(keyCode, event); - mLastKeyCode = KeyEvent.KEYCODE_UNKNOWN; - - if (handled && isPopupShowing()) { - clearListSelection(); - } - - return handled; - } - - /** - * Returns <code>true</code> if the amount of text in the field meets - * or exceeds the {@link #getThreshold} requirement. You can override - * this to impose a different standard for when filtering will be - * triggered. - */ - private boolean enoughToFilter() { - if (DEBUG) Log.v(TAG, "Enough to filter: len=" + getUserText().length() - + " threshold=" + mThreshold); - return getUserText().length() >= mThreshold; - } - - /** - * This is used to watch for edits to the text view. Note that we call - * to methods on the auto complete text view class so that we can access - * private vars without going through thunks. - */ - private class MyWatcher implements TextChangeWatcher { - @Override - public void onTextChanged(String newText) { - doAfterTextChanged(); - } - } - - /** - * @hide - */ - protected void setBlockCompletion(boolean block) { - mBlockCompletion = block; - } - - void doAfterTextChanged() { - if (DEBUG) Log.d(TAG, "doAfterTextChanged(" + getText() + ")"); - if (mBlockCompletion) return; - - // the drop down is shown only when a minimum number of characters - // was typed in the text view - if (enoughToFilter()) { - if (mFilter != null) { - mPopupCanBeUpdated = true; - performFiltering(getUserText(), mLastKeyCode); - buildImeCompletions(); - } - } else { - // drop down is automatically dismissed when enough characters - // are deleted from the text view - if (!mPopup.isDropDownAlwaysVisible()) { - dismissDropDown(); - } - if (mFilter != null) { - performFiltering(null, mLastKeyCode); - } - } - } - - /** - * <p>Indicates whether the popup menu is showing.</p> - * - * @return true if the popup menu is showing, false otherwise - */ - public boolean isPopupShowing() { - return mPopup.isShowing(); - } - - /** - * <p>Converts the selected item from the drop down list into a sequence - * of character that can be used in the edit box.</p> - * - * @param selectedItem the item selected by the user for completion - * - * @return a sequence of characters representing the selected suggestion - */ - protected CharSequence convertSelectionToString(Object selectedItem) { - return mFilter.convertResultToString(selectedItem); - } - - /** - * <p>Clear the list selection. This may only be temporary, as user input will often bring - * it back. - */ - private void clearListSelection() { - mPopup.clearListSelection(); - } - - /** - * <p>Starts filtering the content of the drop down list. The filtering - * pattern is the content of the edit box. Subclasses should override this - * method to filter with a different pattern, for instance a substring of - * <code>text</code>.</p> - * - * @param text the filtering pattern - * @param keyCode the last character inserted in the edit box; beware that - * this will be null when text is being added through a soft input method. - */ - @SuppressWarnings({ "UnusedDeclaration" }) - protected void performFiltering(CharSequence text, int keyCode) { - if (DEBUG) Log.d(TAG, "performFiltering(" + text + ")"); - - mFilter.filter(text, this); - } - - protected void performForcedFiltering() { - boolean wasSuspended = false; - if (mController.isCursorHandlingSuspended()) { - mController.resumeCursorMovementHandlingAndApplyChanges(); - wasSuspended = true; - } - - mFilter.filter(getUserText().toString(), this); - - if (wasSuspended) { - mController.suspendCursorMovementHandling(); - } - } - - /** - * <p>Performs the text completion by converting the selected item from - * the drop down list into a string, replacing the text box's content with - * this string and finally dismissing the drop down menu.</p> - */ - private void performCompletion() { - performCompletion(null, -1, -1); - } - - @Override - public void onCommitCompletion(CompletionInfo completion) { - if (isPopupShowing()) { - mBlockCompletion = true; - replaceText(completion.getText()); - mBlockCompletion = false; - - mPopup.performItemClick(completion.getPosition()); - } - } - - private void performCompletion(View selectedView, int position, long id) { - if (isPopupShowing()) { - Object selectedItem; - if (position < 0) { - selectedItem = mPopup.getSelectedItem(); - } else { - selectedItem = mAdapter.getItem(position); - } - if (selectedItem == null) { - Log.w(TAG, "performCompletion: no selected item"); - return; - } - - mBlockCompletion = true; - replaceText(convertSelectionToString(selectedItem)); - mBlockCompletion = false; - - if (mItemClickListener != null) { - final ListPopupWindow list = mPopup; - - if (selectedView == null || position < 0) { - selectedView = list.getSelectedView(); - position = list.getSelectedItemPosition(); - id = list.getSelectedItemId(); - } - mItemClickListener.onItemClick(list.getListView(), selectedView, position, id); - } - } - - if (mDropDownDismissedOnCompletion && !mPopup.isDropDownAlwaysVisible()) { - dismissDropDown(); - } - } - - /** - * <p>Performs the text completion by replacing the current text by the - * selected item. Subclasses should override this method to avoid replacing - * the whole content of the edit box.</p> - * - * @param text the selected suggestion in the drop down list - */ - protected void replaceText(CharSequence text) { - clearComposingText(); - - setText(text); - // make sure we keep the caret at the end of the text view - Editable spannable = getText(); - Selection.setSelection(spannable, spannable.length()); - } - - /** {@inheritDoc} */ - @Override - public void onFilterComplete(int count) { - updateDropDownForFilter(count); - } - - private void updateDropDownForFilter(int count) { - // Not attached to window, don't update drop-down - if (getWindowVisibility() == View.GONE) return; - - /* - * This checks enoughToFilter() again because filtering requests - * are asynchronous, so the result may come back after enough text - * has since been deleted to make it no longer appropriate - * to filter. - */ - - final boolean dropDownAlwaysVisible = mPopup.isDropDownAlwaysVisible(); - if ((count > 0 || dropDownAlwaysVisible) && enoughToFilter() && - getUserText().length() > 0) { - if (hasFocus() && hasWindowFocus() && mPopupCanBeUpdated) { - showDropDown(); - } - } else if (!dropDownAlwaysVisible && isPopupShowing()) { - dismissDropDown(); - // When the filter text is changed, the first update from the adapter may show an empty - // count (when the query is being performed on the network). Future updates when some - // content has been retrieved should still be able to update the list. - mPopupCanBeUpdated = true; - } - } - - @Override - public void onWindowFocusChanged(boolean hasWindowFocus) { - super.onWindowFocusChanged(hasWindowFocus); - if (!hasWindowFocus && !mPopup.isDropDownAlwaysVisible()) { - dismissDropDown(); - } - } - - @Override - protected void onDisplayHint(int hint) { - super.onDisplayHint(hint); - switch (hint) { - case INVISIBLE: - if (!mPopup.isDropDownAlwaysVisible()) { - dismissDropDown(); - } - break; - } - } - - @Override - protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { - // TextView makes several cursor movements when gaining focus, and this interferes with - // the suggested vs user entered text. Tell the controller to temporarily ignore cursor - // movements while this is going on. - mController.suspendCursorMovementHandling(); - - super.onFocusChanged(focused, direction, previouslyFocusedRect); - // Perform validation if the view is losing focus. - if (!focused) { - performValidation(); - } - if (!focused && !mPopup.isDropDownAlwaysVisible()) { - dismissDropDown(); - } - - mController.resumeCursorMovementHandlingAndApplyChanges(); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - } - - @Override - protected void onDetachedFromWindow() { - dismissDropDown(); - super.onDetachedFromWindow(); - } - - /** - * <p>Closes the drop down if present on screen.</p> - */ - protected void dismissDropDown() { - InputMethodManager imm = InputMethodManager.peekInstance(); - if (imm != null) { - imm.displayCompletions(this, null); - } - mPopup.dismiss(); - mPopupCanBeUpdated = false; - } - - @Override - protected boolean setFrame(final int l, int t, final int r, int b) { - boolean result = super.setFrame(l, t, r, b); - - if (isPopupShowing()) { - showDropDown(); - } - - return result; - } - - /** - * Ensures that the drop down is not obscuring the IME. - * @param visible whether the ime should be in front. If false, the ime is pushed to - * the background. - * @hide internal used only here and SearchDialog - */ - private void ensureImeVisible(boolean visible) { - mPopup.setInputMethodMode(visible - ? ListPopupWindow.INPUT_METHOD_NEEDED : ListPopupWindow.INPUT_METHOD_NOT_NEEDED); - showDropDown(); - } - - /** - * <p>Displays the drop down on screen.</p> - */ - protected void showDropDown() { - if (mPopup.getAnchorView() == null) { - if (mDropDownAnchorId != View.NO_ID) { - mPopup.setAnchorView(getRootView().findViewById(mDropDownAnchorId)); - } else { - mPopup.setAnchorView(this); - } - } - if (!isPopupShowing()) { - // Make sure the list does not obscure the IME when shown for the first time. - mPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NEEDED); - } - mPopup.show(); - } - - private void buildImeCompletions() { - final ListAdapter adapter = mAdapter; - if (adapter != null) { - InputMethodManager imm = InputMethodManager.peekInstance(); - if (imm != null) { - final int count = Math.min(adapter.getCount(), 20); - CompletionInfo[] completions = new CompletionInfo[count]; - int realCount = 0; - - for (int i = 0; i < count; i++) { - if (adapter.isEnabled(i)) { - realCount++; - Object item = adapter.getItem(i); - long id = adapter.getItemId(i); - completions[i] = new CompletionInfo(id, i, - convertSelectionToString(item)); - } - } - - if (realCount != count) { - CompletionInfo[] tmp = new CompletionInfo[realCount]; - System.arraycopy(completions, 0, tmp, 0, realCount); - completions = tmp; - } - - imm.displayCompletions(this, completions); - } - } - } - - private void performValidation() { - } - - /** - * Returns the Filter obtained from {@link Filterable#getFilter}, - * or <code>null</code> if {@link #setAdapter} was not called with - * a Filterable. - */ - protected Filter getFilter() { - return mFilter; - } - - private class DropDownItemClickListener implements AdapterView.OnItemClickListener { - @Override - public void onItemClick(AdapterView parent, View v, int position, long id) { - performCompletion(v, position, id); - } - } - - /** - * Allows us a private hook into the on click event without preventing users from setting - * their own click listener. - */ - private class PassThroughClickListener implements OnClickListener { - - private View.OnClickListener mWrapped; - - /** {@inheritDoc} */ - @Override - public void onClick(View v) { - onClickImpl(); - - if (mWrapped != null) mWrapped.onClick(v); - } - } - - private class PopupDataSetObserver extends DataSetObserver { - @Override - public void onChanged() { - if (mAdapter != null) { - // If the popup is not showing already, showing it will cause - // the list of data set observers attached to the adapter to - // change. We can't do it from here, because we are in the middle - // of iterating through the list of observers. - post(new Runnable() { - @Override - public void run() { - final SuggestionsAdapter adapter = mAdapter; - if (adapter != null) { - // This will re-layout, thus resetting mDataChanged, so that the - // listView click listener stays responsive - updateDropDownForFilter(adapter.getCount()); - } - - updateText(adapter); - } - }); - } - } - } - - public String getUserText() { - return mController.getUserText(); - } - - private void updateText(SuggestionsAdapter adapter) { - if (!BrowserSettings.getInstance().useInstantSearch()) { - return; - } - - if (!isPopupShowing()) { - setSuggestedText(null); - return; - } - - if (mAdapter.getCount() > 0 && !TextUtils.isEmpty(getUserText())) { - for (int i = 0; i < mAdapter.getCount(); ++i) { - SuggestItem current = mAdapter.getItem(i); - if (current.type == SuggestionsAdapter.TYPE_SUGGEST) { - setSuggestedText(current.title); - break; - } - } - } - } - - @Override - public void setText(CharSequence text, BufferType type) { - Editable buffer = getEditableText(); - if (text == null) text = ""; - // if we already have a buffer, we must not replace it with a new one as this will break - // mController. Write the new text into the existing buffer instead. - if (buffer == null) { - super.setText(text, type); - } else { - buffer.replace(0, buffer.length(), text); - invalidate(); - } - } - - public void setText(CharSequence text, boolean filter) { - if (filter) { - setText(text); - } else { - mBlockCompletion = true; - // If cursor movement handling was suspended (the view is - // not in focus), resume it and apply the pending change. - // Since we don't want to perform any filtering, this change - // is safe. - boolean wasSuspended = false; - if (mController.isCursorHandlingSuspended()) { - mController.resumeCursorMovementHandlingAndApplyChanges(); - wasSuspended = true; - } - - setText(text); - - if (wasSuspended) { - mController.suspendCursorMovementHandling(); - } - mBlockCompletion = false; - } - } - - @Override - public Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - if (superState instanceof TextView.SavedState) { - // get rid of TextView's saved state, we override it. - superState = ((TextView.SavedState) superState).getSuperState(); - } - if (superState == null) { - superState = AbsSavedState.EMPTY_STATE; - } - return mController.saveInstanceState(superState); - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - super.onRestoreInstanceState(mController.restoreInstanceState(state)); - } - - public void addQueryTextWatcher(final SuggestedTextController.TextChangeWatcher watcher) { - mController.addUserTextChangeWatcher(watcher); - } - - public void setSuggestedText(String text) { - if (!TextUtils.isEmpty(text)) { - String htmlStripped = Html.fromHtml(text).toString(); - mController.setSuggestedText(htmlStripped); - } else { - mController.setSuggestedText(null); - } - } - - public void getPopupDrawableRect(Rect rect) { - if (mPopup.getListView() != null) { - mPopup.getListView().getDrawingRect(rect); - } - } -} |