Improvement to tap detection for the delete button.
This improvement works as follows:
1) If the user has tapped near the end of the text
and there is some text near where they tapped that is
not a chip, don't send the tap to the chip
and there is no text near where they tapped, send
the tap to the chip
Change-Id: Ifb93ec716d4a9ff1b9dcc2548465280c39d834cf
diff --git a/src/com/android/ex/chips/RecipientEditTextView.java b/src/com/android/ex/chips/RecipientEditTextView.java
index 2e60760..be4fe0d 100644
--- a/src/com/android/ex/chips/RecipientEditTextView.java
+++ b/src/com/android/ex/chips/RecipientEditTextView.java
@@ -35,9 +35,13 @@
import android.text.style.ImageSpan;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.ActionMode;
import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ActionMode.Callback;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListPopupWindow;
@@ -55,7 +59,7 @@
* that use the new Chips UI for addressing a message to recipients.
*/
public class RecipientEditTextView extends MultiAutoCompleteTextView
- implements OnItemClickListener {
+ implements OnItemClickListener, Callback {
private static final String TAG = "RecipientEditTextView";
@@ -93,6 +97,23 @@
mHandler = new Handler();
setOnItemClickListener(this);
mRecipients = new ArrayList<RecipientChip>();
+ setCustomSelectionActionModeCallback(this);
+ }
+
+ @Override
+ public void onSelectionChanged(int start, int end) {
+ // When selection changes, see if it is inside the chips area.
+ // If so, move the cursor back after the chips again.
+ if (mRecipients != null && mRecipients.size() > 0) {
+ Spannable span = getSpannable();
+ RecipientChip[] chips = span.getSpans(start, getText().length(), RecipientChip.class);
+ if (chips != null && chips.length > 0) {
+ // Grab the last chip and set the cursor to after it.
+ setSelection(chips[chips.length - 1].getChipEnd() + 1);
+ }
+ } else {
+ super.onSelectionChanged(start, end);
+ }
}
public RecipientChip constructChipSpan(RecipientEntry contact, int offset, boolean pressed)
@@ -364,18 +385,26 @@
}
}
- // If the offset is beyond where there was any visible text,
- // then leave it should not be pulled into the range of a chip.
- if (offset > realLength) {
+ // If the offset is beyond or at the end of the text,
+ // leave it alone.
+ if (offset >= realLength) {
return offset;
}
- while (offset >= 0 && findChip(offset) == null) {
+ Editable editable = getText();
+ while (offset >= 0 && (findText(editable, offset) == -1 && findChip(offset) == null)) {
// Keep walking backward!
offset--;
}
return offset;
}
+ private int findText(Editable text, int offset) {
+ if (text.charAt(offset) != ' ') {
+ return offset;
+ }
+ return -1;
+ }
+
private RecipientChip findChip(int offset) {
RecipientChip[] chips = getSpannable().getSpans(0, offset, RecipientChip.class);
// Find the chip that contains this offset.
@@ -694,5 +723,25 @@
return mDataId;
}
}
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ return false;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return false;
+ }
+
+ // Prevent selection of chips.
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ return false;
+ }
}