Make suggestion text color change based on the item state.
We support a ColorStateList reference now as a valid font color value in the given html and manage html strings for all supported states which we dynamically set while drawing the items. This will get checked in along with changes to GlobalSearch, EnhancedGoogleSearchProvider and Browser to make them use the new model. Bug: http://b/issue?id=1865037
This commit is contained in:
@@ -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,31 +301,19 @@ 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);
|
||||
String text1 = null;
|
||||
if (mText1Col >= 0) {
|
||||
text1 = cursor.getString(mText1Col);
|
||||
}
|
||||
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 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;
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
private void setViewIcon(Cursor cursor, ImageView v, int iconNameCol) {
|
||||
if (v == null) {
|
||||
return;
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
21
core/res/res/color/search_url_text.xml
Normal file
21
core/res/res/color/search_url_text.xml
Normal file
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user