|
31 | 31 | import android.view.ViewGroup.LayoutParams; |
32 | 32 | import android.view.inputmethod.EditorInfo; |
33 | 33 | import android.view.inputmethod.InputConnection; |
| 34 | +import android.view.inputmethod.InputConnectionWrapper; |
34 | 35 | import android.widget.Filter; |
35 | 36 | import android.widget.ListView; |
36 | 37 | import android.widget.MultiAutoCompleteTextView; |
@@ -306,7 +307,7 @@ public void performCompletion() { |
306 | 307 | @Override |
307 | 308 | public InputConnection onCreateInputConnection(EditorInfo outAttrs) { |
308 | 309 | //Override normal multiline text handling of enter/done and force a done button |
309 | | - InputConnection connection = super.onCreateInputConnection(outAttrs); |
| 310 | + TokenInputConnection connection = new TokenInputConnection(super.onCreateInputConnection(outAttrs), true); |
310 | 311 | int imeActions = outAttrs.imeOptions&EditorInfo.IME_MASK_ACTION; |
311 | 312 | if ((imeActions&EditorInfo.IME_ACTION_DONE) != 0) { |
312 | 313 | // clear the existing action |
@@ -363,24 +364,30 @@ public boolean onKeyDown(int keyCode, KeyEvent event) { |
363 | 364 | } |
364 | 365 | break; |
365 | 366 | case KeyEvent.KEYCODE_DEL: |
366 | | - if (tokenClickStyle != null && tokenClickStyle.isSelectable()) { |
367 | | - Editable text = getText(); |
368 | | - if (text == null) break; |
369 | | - |
370 | | - TokenImageSpan[] spans = text.getSpans(0, text.length(), TokenImageSpan.class); |
371 | | - for (TokenImageSpan span: spans) { |
372 | | - if (span.view.isSelected()) { |
373 | | - removeSpan(span); |
374 | | - handled = true; |
375 | | - break; |
376 | | - } |
377 | | - } |
378 | | - } |
| 367 | + handled = deleteSelectedObject(handled); |
| 368 | + break; |
379 | 369 | } |
380 | 370 |
|
381 | 371 | return handled || super.onKeyDown(keyCode, event); |
382 | 372 | } |
383 | 373 |
|
| 374 | + private boolean deleteSelectedObject(boolean handled) { |
| 375 | + if (tokenClickStyle != null && tokenClickStyle.isSelectable()) { |
| 376 | + Editable text = getText(); |
| 377 | + if (text == null) return handled; |
| 378 | + |
| 379 | + TokenImageSpan[] spans = text.getSpans(0, text.length(), TokenImageSpan.class); |
| 380 | + for (TokenImageSpan span: spans) { |
| 381 | + if (span.view.isSelected()) { |
| 382 | + removeSpan(span); |
| 383 | + handled = true; |
| 384 | + break; |
| 385 | + } |
| 386 | + } |
| 387 | + } |
| 388 | + return handled; |
| 389 | + } |
| 390 | + |
384 | 391 | @Override |
385 | 392 | public boolean onEditorAction(TextView view, int action, KeyEvent keyEvent) { |
386 | 393 | if (action == EditorInfo.IME_ACTION_DONE) { |
@@ -1224,4 +1231,22 @@ public SavedState[] newArray(int size) { |
1224 | 1231 | } |
1225 | 1232 | }; |
1226 | 1233 | } |
| 1234 | + |
| 1235 | + private class TokenInputConnection extends InputConnectionWrapper { |
| 1236 | + |
| 1237 | + public TokenInputConnection(InputConnection target, boolean mutable) { |
| 1238 | + super(target, mutable); |
| 1239 | + } |
| 1240 | + |
| 1241 | + // This will fire if the soft keyboard delete key is pressed. |
| 1242 | + // The onKeyPressed method does not always do this. |
| 1243 | + @Override |
| 1244 | + public boolean deleteSurroundingText(int beforeLength, int afterLength) { |
| 1245 | + if (deleteSelectedObject(false)) { |
| 1246 | + return true; |
| 1247 | + } else { |
| 1248 | + return super.deleteSurroundingText(beforeLength, afterLength); |
| 1249 | + } |
| 1250 | + } |
| 1251 | + } |
1227 | 1252 | } |
0 commit comments