summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormindyp <mindyp@google.com>2012-11-30 17:13:34 -0800
committermindyp <mindyp@google.com>2012-12-03 08:45:54 -0800
commit0a9b6b9d977cb4a51a5920721eb3f594e35aca98 (patch)
tree3579a1dfcdc282e545cf6f878d2e5026ef69ec29
parenteec98f9f7701a66f3f9f0eaceefbf5a87e218978 (diff)
downloadandroid_frameworks_ex-0a9b6b9d977cb4a51a5920721eb3f594e35aca98.tar.gz
android_frameworks_ex-0a9b6b9d977cb4a51a5920721eb3f594e35aca98.tar.bz2
android_frameworks_ex-0a9b6b9d977cb4a51a5920721eb3f594e35aca98.zip
mMaxLines was not being set correctly; dont draw hidden chips on first render pass
mMaxLines was always zero Setting the value correctly avoids an extra layout which makes it faster to render chips Use an "invisible" recipient chip for anything > than max chips we can show before showing the more chip; this avoids a lot of unnecessary drawing and decoding of 9 patches in the first pass; once these are resolved (or the user makes them visible), they will be correctly drawn as visible chips Part of b/7492291 First 2 contacts takes too long to resolve into chips when there are many contacts Change-Id: I37817381f93efb968940031d8a8b77fb62c8919a
-rw-r--r--chips/res/values/dimen.xml1
-rw-r--r--chips/src/com/android/ex/chips/InvisibleRecipientChip.java135
-rw-r--r--chips/src/com/android/ex/chips/RecipientChip.java90
-rw-r--r--chips/src/com/android/ex/chips/RecipientEditTextView.java42
-rw-r--r--chips/src/com/android/ex/chips/VisibleRecipientChip.java124
5 files changed, 313 insertions, 79 deletions
diff --git a/chips/res/values/dimen.xml b/chips/res/values/dimen.xml
index b93555f..98354d2 100644
--- a/chips/res/values/dimen.xml
+++ b/chips/res/values/dimen.xml
@@ -19,4 +19,5 @@
<dimen name="chip_height">32dip</dimen>
<dimen name="chip_text_size">14sp</dimen>
<dimen name="line_spacing_extra">4dip</dimen>
+ <integer name="chips_max_lines">-1</integer>
</resources> \ No newline at end of file
diff --git a/chips/src/com/android/ex/chips/InvisibleRecipientChip.java b/chips/src/com/android/ex/chips/InvisibleRecipientChip.java
new file mode 100644
index 0000000..46fe19a
--- /dev/null
+++ b/chips/src/com/android/ex/chips/InvisibleRecipientChip.java
@@ -0,0 +1,135 @@
+/*
+ * 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.ex.chips;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Paint.FontMetricsInt;
+import android.graphics.Rect;
+import android.text.TextUtils;
+import android.text.style.ReplacementSpan;
+
+/**
+ * RecipientChip defines a span that contains information relevant to a
+ * particular recipient.
+ */
+/* package */class InvisibleRecipientChip extends ReplacementSpan implements RecipientChip {
+ private final CharSequence mDisplay;
+
+ private final CharSequence mValue;
+
+ private final long mContactId;
+
+ private final long mDataId;
+
+ private RecipientEntry mEntry;
+
+ private boolean mSelected = false;
+
+ private CharSequence mOriginalText;
+
+ public InvisibleRecipientChip(RecipientEntry entry, int offset) {
+ super();
+ mDisplay = entry.getDisplayName();
+ mValue = entry.getDestination().trim();
+ mContactId = entry.getContactId();
+ mDataId = entry.getDataId();
+ mEntry = entry;
+ }
+
+ /**
+ * Set the selected state of the chip.
+ * @param selected
+ */
+ public void setSelected(boolean selected) {
+ mSelected = selected;
+ }
+
+ /**
+ * Return true if the chip is selected.
+ */
+ public boolean isSelected() {
+ return mSelected;
+ }
+
+ /**
+ * Get the text displayed in the chip.
+ */
+ public CharSequence getDisplay() {
+ return mDisplay;
+ }
+
+ /**
+ * Get the text value this chip represents.
+ */
+ public CharSequence getValue() {
+ return mValue;
+ }
+
+ /**
+ * Get the id of the contact associated with this chip.
+ */
+ public long getContactId() {
+ return mContactId;
+ }
+
+ /**
+ * Get the id of the data associated with this chip.
+ */
+ public long getDataId() {
+ return mDataId;
+ }
+
+ /**
+ * Get associated RecipientEntry.
+ */
+ public RecipientEntry getEntry() {
+ return mEntry;
+ }
+
+ public void setOriginalText(String text) {
+ if (!TextUtils.isEmpty(text)) {
+ text = text.trim();
+ }
+ mOriginalText = text;
+ }
+
+ public CharSequence getOriginalText() {
+ return !TextUtils.isEmpty(mOriginalText) ? mOriginalText : mEntry.getDestination();
+ }
+
+ @Override
+ public void draw(Canvas arg0, CharSequence arg1, int arg2, int arg3, float arg4, int arg5,
+ int arg6, int arg7, Paint arg8) {
+ // Do nothing.
+ }
+
+ @Override
+ public int getSize(Paint arg0, CharSequence arg1, int arg2, int arg3, FontMetricsInt arg4) {
+ return 0;
+ }
+
+ @Override
+ public Rect getBounds() {
+ return new Rect(0, 0, 0, 0);
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ // do nothing.
+ }
+}
diff --git a/chips/src/com/android/ex/chips/RecipientChip.java b/chips/src/com/android/ex/chips/RecipientChip.java
index 0f93a0d..c7745c2 100644
--- a/chips/src/com/android/ex/chips/RecipientChip.java
+++ b/chips/src/com/android/ex/chips/RecipientChip.java
@@ -16,97 +16,69 @@
package com.android.ex.chips;
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-import android.text.style.DynamicDrawableSpan;
-import android.text.style.ImageSpan;
+import android.graphics.Canvas;
+import android.graphics.Rect;
/**
- * RecipientChip defines an ImageSpan that contains information relevant to a
+ * RecipientChip defines a drawable object that contains information relevant to a
* particular recipient.
*/
-/* package */class RecipientChip extends ImageSpan {
- private final CharSequence mDisplay;
-
- private final CharSequence mValue;
-
- private final long mContactId;
-
- private final long mDataId;
-
- private RecipientEntry mEntry;
-
- private boolean mSelected = false;
-
- private CharSequence mOriginalText;
-
- public RecipientChip(Drawable drawable, RecipientEntry entry, int offset) {
- super(drawable, DynamicDrawableSpan.ALIGN_BOTTOM);
- mDisplay = entry.getDisplayName();
- mValue = entry.getDestination().trim();
- mContactId = entry.getContactId();
- mDataId = entry.getDataId();
- mEntry = entry;
- }
+/* package */interface RecipientChip {
/**
* Set the selected state of the chip.
* @param selected
*/
- public void setSelected(boolean selected) {
- mSelected = selected;
- }
-
+ public void setSelected(boolean selected);
/**
* Return true if the chip is selected.
*/
- public boolean isSelected() {
- return mSelected;
- }
+ public boolean isSelected();
/**
* Get the text displayed in the chip.
*/
- public CharSequence getDisplay() {
- return mDisplay;
- }
+ public CharSequence getDisplay();
/**
* Get the text value this chip represents.
*/
- public CharSequence getValue() {
- return mValue;
- }
+ public CharSequence getValue();
/**
* Get the id of the contact associated with this chip.
*/
- public long getContactId() {
- return mContactId;
- }
+ public long getContactId();
/**
* Get the id of the data associated with this chip.
*/
- public long getDataId() {
- return mDataId;
- }
+ public long getDataId();
/**
* Get associated RecipientEntry.
*/
- public RecipientEntry getEntry() {
- return mEntry;
- }
+ public RecipientEntry getEntry();
+
+ /**
+ * Set the text in the edittextview originally associated with this chip
+ * before any reverse lookups.
+ */
+ public void setOriginalText(String text);
- public void setOriginalText(String text) {
- if (!TextUtils.isEmpty(text)) {
- text = text.trim();
- }
- mOriginalText = text;
- }
+ /**
+ * Set the text in the edittextview originally associated with this chip
+ * before any reverse lookups.
+ */
+ public CharSequence getOriginalText();
- public CharSequence getOriginalText() {
- return !TextUtils.isEmpty(mOriginalText) ? mOriginalText : mEntry.getDestination();
- }
+ /**
+ * Get the bounds of the chip; may be 0,0 if it is not visibly rendered.
+ */
+ public Rect getBounds();
+
+ /**
+ * Draw the chip.
+ */
+ public void draw(Canvas canvas);
}
diff --git a/chips/src/com/android/ex/chips/RecipientEditTextView.java b/chips/src/com/android/ex/chips/RecipientEditTextView.java
index 6b20216..645f190 100644
--- a/chips/src/com/android/ex/chips/RecipientEditTextView.java
+++ b/chips/src/com/android/ex/chips/RecipientEditTextView.java
@@ -273,7 +273,6 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements
addTextChangedListener(mTextWatcher);
mGestureDetector = new GestureDetector(context, this);
setOnEditorActionListener(this);
- mMaxLines = getLineCount();
}
@Override
@@ -633,7 +632,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements
// Pass the full text, un-ellipsized, to the chip.
Drawable result = new BitmapDrawable(getResources(), tmpBitmap);
result.setBounds(0, 0, tmpBitmap.getWidth(), tmpBitmap.getHeight());
- RecipientChip recipientChip = new RecipientChip(result, contact, offset);
+ RecipientChip recipientChip = new VisibleRecipientChip(result, contact, offset);
// Return text to the original size.
paint.setTextSize(defaultSize);
paint.setColor(defaultColor);
@@ -707,7 +706,8 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements
if (mInvalidChipBackground == null) {
mInvalidChipBackground = r.getDrawable(R.drawable.chip_background_invalid);
}
- mLineSpacingExtra = context.getResources().getDimension(R.dimen.line_spacing_extra);
+ mLineSpacingExtra = r.getDimension(R.dimen.line_spacing_extra);
+ mMaxLines = r.getInteger(R.integer.chips_max_lines);
a.recycle();
}
@@ -772,7 +772,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements
if (chips != null) {
Rect bounds;
for (RecipientChip chip : chips) {
- bounds = chip.getDrawable().getBounds();
+ bounds = chip.getBounds();
if (getWidth() > 0 && bounds.right - bounds.left > getWidth()) {
// Need to redraw that chip.
replaceChip(chip, chip.getEntry());
@@ -808,7 +808,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements
&& editable.charAt(tokenEnd) == COMMIT_CHAR_COMMA) {
tokenEnd++;
}
- createReplacementChip(tokenStart, tokenEnd, editable);
+ createReplacementChip(tokenStart, tokenEnd, editable, i < CHIP_LIMIT);
}
mPendingChipsCount--;
}
@@ -863,16 +863,15 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements
}
// Find the last chip; eliminate any commit characters after it.
RecipientChip[] chips = getSortedRecipients();
+ Spannable spannable = getSpannable();
if (chips != null && chips.length > 0) {
int end;
- ImageSpan lastSpan;
mMoreChip = getMoreChip();
if (mMoreChip != null) {
- lastSpan = mMoreChip;
+ end = spannable.getSpanEnd(mMoreChip);
} else {
- lastSpan = getLastChip();
+ end = getSpannable().getSpanEnd(getLastChip());
}
- end = getSpannable().getSpanEnd(lastSpan);
Editable editable = getText();
int length = editable.length();
if (length > end) {
@@ -890,7 +889,8 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements
* Create a chip that represents just the email address of a recipient. At some later
* point, this chip will be attached to a real contact entry, if one exists.
*/
- private void createReplacementChip(int tokenStart, int tokenEnd, Editable editable) {
+ private void createReplacementChip(int tokenStart, int tokenEnd, Editable editable,
+ boolean visible) {
if (alreadyHasChip(tokenStart, tokenEnd)) {
// There is already a chip present at this location.
// Don't recreate it.
@@ -908,14 +908,16 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements
RecipientChip chip = null;
try {
if (!mNoChips) {
- /* leave space for the contact icon if this is not just an email address */
- chip = constructChipSpan(
- entry,
- tokenStart,
- false,
- TextUtils.isEmpty(entry.getDisplayName())
- || TextUtils.equals(entry.getDisplayName(),
- entry.getDestination()));
+ /*
+ * leave space for the contact icon if this is not just an
+ * email address
+ */
+ boolean leaveSpace = TextUtils.isEmpty(entry.getDisplayName())
+ || TextUtils.equals(entry.getDisplayName(),
+ entry.getDestination());
+ chip = visible ?
+ constructChipSpan(entry, tokenStart, false, leaveSpace)
+ : new InvisibleRecipientChip(entry, commitCharIndex);
}
} catch (NullPointerException e) {
Log.e(TAG, e.getMessage(), e);
@@ -2580,14 +2582,14 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements
@Override
public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
- Rect rect = mChip.getDrawable().getBounds();
+ Rect rect = mChip.getBounds();
shadowSize.set(rect.width(), rect.height());
shadowTouchPoint.set(rect.centerX(), rect.centerY());
}
@Override
public void onDrawShadow(Canvas canvas) {
- mChip.getDrawable().draw(canvas);
+ mChip.draw(canvas);
}
}
diff --git a/chips/src/com/android/ex/chips/VisibleRecipientChip.java b/chips/src/com/android/ex/chips/VisibleRecipientChip.java
new file mode 100644
index 0000000..257e3f4
--- /dev/null
+++ b/chips/src/com/android/ex/chips/VisibleRecipientChip.java
@@ -0,0 +1,124 @@
+/*
+ * 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.ex.chips;
+
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.text.style.DynamicDrawableSpan;
+import android.text.style.ImageSpan;
+
+/**
+ * VisibleRecipientChip defines an ImageSpan that contains information relevant to a
+ * particular recipient and renders a background asset to go with it.
+ */
+/* package */class VisibleRecipientChip extends ImageSpan implements RecipientChip {
+ private final CharSequence mDisplay;
+
+ private final CharSequence mValue;
+
+ private final long mContactId;
+
+ private final long mDataId;
+
+ private RecipientEntry mEntry;
+
+ private boolean mSelected = false;
+
+ private CharSequence mOriginalText;
+
+ public VisibleRecipientChip(Drawable drawable, RecipientEntry entry, int offset) {
+ super(drawable, DynamicDrawableSpan.ALIGN_BOTTOM);
+ mDisplay = entry.getDisplayName();
+ mValue = entry.getDestination().trim();
+ mContactId = entry.getContactId();
+ mDataId = entry.getDataId();
+ mEntry = entry;
+ }
+
+ /**
+ * Set the selected state of the chip.
+ * @param selected
+ */
+ public void setSelected(boolean selected) {
+ mSelected = selected;
+ }
+
+ /**
+ * Return true if the chip is selected.
+ */
+ public boolean isSelected() {
+ return mSelected;
+ }
+
+ /**
+ * Get the text displayed in the chip.
+ */
+ public CharSequence getDisplay() {
+ return mDisplay;
+ }
+
+ /**
+ * Get the text value this chip represents.
+ */
+ public CharSequence getValue() {
+ return mValue;
+ }
+
+ /**
+ * Get the id of the contact associated with this chip.
+ */
+ public long getContactId() {
+ return mContactId;
+ }
+
+ /**
+ * Get the id of the data associated with this chip.
+ */
+ public long getDataId() {
+ return mDataId;
+ }
+
+ /**
+ * Get associated RecipientEntry.
+ */
+ public RecipientEntry getEntry() {
+ return mEntry;
+ }
+
+ public void setOriginalText(String text) {
+ if (!TextUtils.isEmpty(text)) {
+ text = text.trim();
+ }
+ mOriginalText = text;
+ }
+
+ public CharSequence getOriginalText() {
+ return !TextUtils.isEmpty(mOriginalText) ? mOriginalText : mEntry.getDestination();
+ }
+
+ @Override
+ public Rect getBounds() {
+ return getDrawable().getBounds();
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ getDrawable().draw(canvas);
+ }
+}