diff options
-rw-r--r-- | core/java/android/app/SuggestionsAdapter.java | 145 | ||||
-rw-r--r-- | core/res/res/color/search_url_text.xml | 21 | ||||
-rw-r--r-- | core/res/res/values/colors.xml | 4 |
3 files changed, 146 insertions, 24 deletions
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java index 49c94d1..c8e952f 100644 --- a/core/java/android/app/SuggestionsAdapter.java +++ b/core/java/android/app/SuggestionsAdapter.java @@ -18,7 +18,8 @@ package android.app; import android.content.ContentResolver; import android.content.Context; -import android.content.res.Resources.NotFoundException; +import android.content.res.ColorStateList; +import android.content.res.Resources; import android.database.Cursor; import android.graphics.Canvas; import android.graphics.drawable.Drawable; @@ -300,29 +301,17 @@ class SuggestionsAdapter extends ResourceCursorAdapter { ((SuggestionItemView)view).setColor(backgroundColor); final boolean isHtml = mFormatCol > 0 && "html".equals(cursor.getString(mFormatCol)); - setViewText(cursor, views.mText1, mText1Col, isHtml); - setViewText(cursor, views.mText2, mText2Col, isHtml); - setViewIcon(cursor, views.mIcon1, mIconName1Col); - setViewIcon(cursor, views.mIcon2, mIconName2Col); - } - - private void setViewText(Cursor cursor, TextView v, int textCol, boolean isHtml) { - if (v == null) { - return; - } - CharSequence text = null; - if (textCol >= 0) { - String str = cursor.getString(textCol); - text = (str != null && isHtml) ? Html.fromHtml(str) : str; + String text1 = null; + if (mText1Col >= 0) { + text1 = cursor.getString(mText1Col); } - // Set the text even if it's null, since we need to clear any previous text. - v.setText(text); - - if (TextUtils.isEmpty(text)) { - v.setVisibility(View.GONE); - } else { - v.setVisibility(View.VISIBLE); + String text2 = null; + if (mText2Col >= 0) { + text2 = cursor.getString(mText2Col); } + ((SuggestionItemView)view).setTextStrings(text1, text2, isHtml, mProviderContext); + setViewIcon(cursor, views.mIcon1, mIconName1Col); + setViewIcon(cursor, views.mIcon2, mIconName2Col); } private void setViewIcon(Cursor cursor, ImageView v, int iconNameCol) { @@ -476,7 +465,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter { if (drawable != null) { mOutsideDrawablesCache.put(drawableId, drawable); } - } catch (NotFoundException nfe) { + } catch (Resources.NotFoundException nfe) { if (DBG) Log.d(LOG_TAG, "Icon resource not found: " + drawableId); // drawable = null; } @@ -509,8 +498,82 @@ class SuggestionsAdapter extends ResourceCursorAdapter { * draws on top of the list view selection highlight). */ private class SuggestionItemView extends ViewGroup { + /** + * Parses a given HTMl string and manages Spannable variants of the string for different + * states of the suggestion item (selected, pressed and normal). Colors for these different + * states are specified in the html font tag color attribute in the format '@<RESOURCEID>' + * where RESOURCEID is the ID of a ColorStateList or Color resource. + */ + private class MultiStateText { + private CharSequence mNormal = null; // text to display in normal state. + private CharSequence mSelected = null; // text to display in selected state. + private CharSequence mPressed = null; // text to display in pressed state. + private String mPlainText = null; // valid if the text is stateless plain text. + + public MultiStateText(boolean isHtml, String text, Context context) { + if (!isHtml || text == null) { + mPlainText = text; + return; + } + + String textNormal = text; + String textSelected = text; + String textPressed = text; + int textLength = text.length(); + int start = text.indexOf("\"@"); + + // For each font color attribute which has the value in the form '@<RESOURCEID>', + // try to load the resource and create the display strings for the 3 states. + while (start >= 0) { + start++; + int end = text.indexOf("\"", start); + if (end == -1) break; + + String colorIdString = text.substring(start, end); + int colorId = Integer.parseInt(colorIdString.substring(1)); + try { + // The following call works both for color lists and colors. + ColorStateList csl = context.getResources().getColorStateList(colorId); + int normalColor = csl.getColorForState( + View.EMPTY_STATE_SET, csl.getDefaultColor()); + int selectedColor = csl.getColorForState( + View.SELECTED_STATE_SET, csl.getDefaultColor()); + int pressedColor = csl.getColorForState( + View.PRESSED_STATE_SET, csl.getDefaultColor()); + + // Convert the int color values into a hex string, and strip the first 2 + // characters which will be the alpha (html doesn't want this). + textNormal = textNormal.replace(colorIdString, + "#" + Integer.toHexString(normalColor).substring(2)); + textSelected = textSelected.replace(colorIdString, + "#" + Integer.toHexString(selectedColor).substring(2)); + textPressed = textPressed.replace(colorIdString, + "#" + Integer.toHexString(pressedColor).substring(2)); + } catch (Resources.NotFoundException e) { + // Nothing to do. + } + + start = text.indexOf("\"@", end); + } + mNormal = Html.fromHtml(textNormal); + mSelected = Html.fromHtml(textSelected); + mPressed = Html.fromHtml(textPressed); + } + public CharSequence normal() { + return (mPlainText != null) ? mPlainText : mNormal; + } + public CharSequence selected() { + return (mPlainText != null) ? mPlainText : mSelected; + } + public CharSequence pressed() { + return (mPlainText != null) ? mPlainText : mPressed; + } + } + private int mBackgroundColor; // the background color to draw in normal state. private View mView; // the suggestion item's view. + private MultiStateText mText1Strings = null; + private MultiStateText mText2Strings = null; protected SuggestionItemView(Context context, Cursor cursor) { // Initialize ourselves @@ -537,12 +600,48 @@ class SuggestionsAdapter extends ResourceCursorAdapter { } } + private void setInitialTextForView(TextView view, MultiStateText multiState, + String plainText) { + // Set the text even if it's null, since we need to clear any previous text. + CharSequence text = (multiState != null) ? multiState.normal() : plainText; + view.setText(text); + + if (TextUtils.isEmpty(text)) { + view.setVisibility(View.GONE); + } else { + view.setVisibility(View.VISIBLE); + } + } + + public void setTextStrings(String text1, String text2, boolean isHtml, Context context) { + mText1Strings = new MultiStateText(isHtml, text1, context); + mText2Strings = new MultiStateText(isHtml, text2, context); + + ChildViewCache views = (ChildViewCache) getTag(); + setInitialTextForView(views.mText1, mText1Strings, text1); + setInitialTextForView(views.mText2, mText2Strings, text2); + } + + public void updateTextViewContentIfRequired() { + // Check if the pressed or selected state has changed since the last call. + boolean isPressedNow = isPressed(); + boolean isSelectedNow = isSelected(); + + ChildViewCache views = (ChildViewCache) getTag(); + views.mText1.setText((isPressedNow ? mText1Strings.pressed() : + (isSelectedNow ? mText1Strings.selected() : mText1Strings.normal()))); + views.mText2.setText((isPressedNow ? mText2Strings.pressed() : + (isSelectedNow ? mText2Strings.selected() : mText2Strings.normal()))); + } + public void setColor(int backgroundColor) { mBackgroundColor = backgroundColor; } @Override public void dispatchDraw(Canvas canvas) { + updateTextViewContentIfRequired(); + if (mBackgroundColor != 0 && !isPressed() && !isSelected()) { canvas.drawColor(mBackgroundColor); } diff --git a/core/res/res/color/search_url_text.xml b/core/res/res/color/search_url_text.xml new file mode 100644 index 0000000..449fdf0 --- /dev/null +++ b/core/res/res/color/search_url_text.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2009 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:color="@android:color/search_url_text_pressed"/> + <item android:state_selected="true" android:color="@android:color/search_url_text_selected"/> + <item android:color="@android:color/search_url_text_normal"/> <!-- not selected --> +</selector> diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index d284d0f..b7de997 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -74,7 +74,9 @@ <color name="perms_normal_perm_color">#c0c0c0</color> <!-- For search-related UIs --> - <color name="search_url_text">#7fa87f</color> + <color name="search_url_text_normal">#7fa87f</color> + <color name="search_url_text_selected">@android:color/black</color> + <color name="search_url_text_pressed">@android:color/black</color> <color name="search_widget_corpus_item_background">@android:color/lighter_gray</color> </resources> |