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> | 
