Merge commit 'f54b3505' into manualmerge
Conflicts:
chips/src/com/android/ex/chips/RecipientEditTextView.java
Change-Id: I2a8d55d6db3fdb4aab6ea788b685a047dcf9ed9d
diff --git a/src/com/android/ex/chips/BaseRecipientAdapter.java b/src/com/android/ex/chips/BaseRecipientAdapter.java
index 53f3625..b6d4fa8 100644
--- a/src/com/android/ex/chips/BaseRecipientAdapter.java
+++ b/src/com/android/ex/chips/BaseRecipientAdapter.java
@@ -499,6 +499,8 @@
private final DelayedMessageHandler mDelayedMessageHandler = new DelayedMessageHandler();
+ private EntriesUpdatedObserver mEntriesUpdatedObserver;
+
/**
* Constructor for email queries.
*/
@@ -706,9 +708,14 @@
return entries;
}
+ public void registerUpdateObserver(EntriesUpdatedObserver observer) {
+ mEntriesUpdatedObserver = observer;
+ }
+
/** Resets {@link #mEntries} and notify the event to its parent ListView. */
private void updateEntries(List<RecipientEntry> newEntries) {
mEntries = newEntries;
+ mEntriesUpdatedObserver.onChanged(newEntries);
notifyDataSetChanged();
}
@@ -967,4 +974,12 @@
protected int getPhotoId() {
return android.R.id.icon;
}
+
+ /**
+ * Interface called before the BaseRecipientAdapter updates recipient
+ * results in the popup window.
+ */
+ protected interface EntriesUpdatedObserver {
+ public void onChanged(List<RecipientEntry> entries);
+ }
}
diff --git a/src/com/android/ex/chips/RecipientEditTextView.java b/src/com/android/ex/chips/RecipientEditTextView.java
index 29787ab..c346c4b 100644
--- a/src/com/android/ex/chips/RecipientEditTextView.java
+++ b/src/com/android/ex/chips/RecipientEditTextView.java
@@ -53,6 +53,7 @@
import android.text.util.Rfc822Tokenizer;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.TypedValue;
import android.util.Patterns;
import android.view.ActionMode;
import android.view.ActionMode.Callback;
@@ -71,6 +72,7 @@
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
+import android.widget.Filterable;
import android.widget.ListAdapter;
import android.widget.ListPopupWindow;
import android.widget.ListView;
@@ -85,6 +87,7 @@
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -234,6 +237,10 @@
private int mMaxLines;
+ private static int sExcessTopPadding = -1;
+
+ private int mActionBarHeight;
+
public RecipientEditTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setChipDimensions(context, attrs);
@@ -396,6 +403,44 @@
}
}
+ private int getExcessTopPadding() {
+ if (sExcessTopPadding == -1) {
+ sExcessTopPadding = (int) mChipHeight;
+ }
+ return sExcessTopPadding;
+ }
+
+ public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
+ super.setAdapter(adapter);
+ ((BaseRecipientAdapter) adapter)
+ .registerUpdateObserver(new BaseRecipientAdapter.EntriesUpdatedObserver() {
+ @Override
+ public void onChanged(List<RecipientEntry> entries) {
+ // Scroll the chips field to the top of the screen so
+ // that the user can see as many results as possible.
+ if (entries != null && entries.size() > 0) {
+ scrollBottomIntoView();
+ }
+ }
+ });
+ }
+
+ private void scrollBottomIntoView() {
+ if (mScrollView != null && mShouldShrink) {
+ int[] location = new int[2];
+ getLocationOnScreen(location);
+ int height = getHeight();
+ int currentPos = location[1] + height;
+ // Desired position shows at least 1 line of chips below the action
+ // bar. We add excess padding to make sure this is always below other
+ // content.
+ int desiredPos = (int) mChipHeight + mActionBarHeight + getExcessTopPadding();
+ if (currentPos > desiredPos) {
+ mScrollView.scrollBy(0, currentPos - desiredPos);
+ }
+ }
+ }
+
@Override
public void performValidation() {
// Do nothing. Chips handles its own validation.
@@ -708,6 +753,12 @@
}
mLineSpacingExtra = r.getDimension(R.dimen.line_spacing_extra);
mMaxLines = r.getInteger(R.integer.chips_max_lines);
+ TypedValue tv = new TypedValue();
+ if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
+ mActionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources()
+ .getDisplayMetrics());
+ }
+
a.recycle();
}
@@ -1297,7 +1348,8 @@
*/
@Override
protected void performFiltering(CharSequence text, int keyCode) {
- if (enoughToFilter() && !isCompletedToken(text)) {
+ boolean isCompletedToken = isCompletedToken(text);
+ if (enoughToFilter() && !isCompletedToken) {
int end = getSelectionEnd();
int start = mTokenizer.findTokenStart(text, end);
// If this is a RecipientChip, don't filter
@@ -1307,6 +1359,8 @@
if (chips != null && chips.length > 0) {
return;
}
+ } else if (isCompletedToken) {
+ return;
}
super.performFiltering(text, keyCode);
}
@@ -1387,7 +1441,7 @@
private void scrollLineIntoView(int line) {
if (mScrollView != null) {
- mScrollView.scrollBy(0, calculateOffsetFromBottom(line));
+ mScrollView.smoothScrollBy(0, calculateOffsetFromBottom(line));
}
}
@@ -2202,15 +2256,6 @@
editable.delete(tokenStart, tokenEnd);
getSpannable().removeSpan(repl[0]);
}
- } else if (count > before) {
- if (mSelectedChip != null
- && isGeneratedContact(mSelectedChip)) {
- if (lastCharacterIsCommitCharacter(s)) {
- commitByCharacter();
- return;
- }
- }
- scrollBottomIntoView();
}
}
@@ -2220,12 +2265,6 @@
}
}
- private void scrollBottomIntoView() {
- if (mScrollView != null) {
- mScrollView.scrollBy(0, (int) (getLineCount() * mChipHeight));
- }
- }
-
public boolean lastCharacterIsCommitCharacter(CharSequence s) {
char last;
int end = getSelectionEnd() == 0 ? 0 : getSelectionEnd() - 1;