Skip to content

Commit ebb84f8

Browse files
committed
Return useful accessibility string
1 parent 88f92e4 commit ebb84f8

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

library/src/main/java/com/tokenautocomplete/TokenCompleteTextView.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import android.text.InputFilter;
1414
import android.text.InputType;
1515
import android.text.Layout;
16+
import android.text.Selection;
1617
import android.text.SpanWatcher;
1718
import android.text.Spannable;
1819
import android.text.SpannableStringBuilder;
@@ -25,6 +26,7 @@
2526
import android.view.KeyEvent;
2627
import android.view.MotionEvent;
2728
import android.view.View;
29+
import android.view.accessibility.AccessibilityEvent;
2830
import android.view.inputmethod.EditorInfo;
2931
import android.view.inputmethod.ExtractedText;
3032
import android.view.inputmethod.ExtractedTextRequest;
@@ -399,6 +401,77 @@ public void setTokenLimit(int tokenLimit) {
399401
*/
400402
abstract protected T defaultObject(String completionText);
401403

404+
/**
405+
* Correctly build accessibility string for token contents
406+
*
407+
* This seems to be a hidden API, but there doesn't seem to be another reasonable way
408+
* @return custom string for accessibility
409+
*/
410+
@SuppressWarnings("unused")
411+
public CharSequence getTextForAccessibility() {
412+
if (getObjects().size() == 0) {
413+
return getText();
414+
}
415+
416+
SpannableStringBuilder description = new SpannableStringBuilder();
417+
Editable text = getText();
418+
int selectionStart = -1;
419+
int selectionEnd = -1;
420+
int i;
421+
//Need to take the existing tet buffer and
422+
// - replace all tokens with a decent string representation of the object
423+
// - set the selection span to the corresponding location in the new CharSequence
424+
for (i = 0; i < text.length(); ++i) {
425+
//See if this is where we should start the selection
426+
int origSelectionStart = Selection.getSelectionStart(text);
427+
if (i == origSelectionStart) {
428+
selectionStart = description.length();
429+
}
430+
int origSelectionEnd = Selection.getSelectionEnd(text);
431+
if (i == origSelectionEnd) {
432+
selectionEnd = description.length();
433+
}
434+
435+
//Replace token spans
436+
TokenImageSpan[] tokens = text.getSpans(i, i, TokenImageSpan.class);
437+
if (tokens.length > 0) {
438+
TokenImageSpan token = tokens[0];
439+
description = description.append(tokenizer.terminateToken(token.getToken().toString()));
440+
i = text.getSpanEnd(token);
441+
continue;
442+
}
443+
444+
description = description.append(text.subSequence(i, i + 1));
445+
}
446+
447+
int origSelectionStart = Selection.getSelectionStart(text);
448+
if (i == origSelectionStart) {
449+
selectionStart = description.length();
450+
}
451+
int origSelectionEnd = Selection.getSelectionEnd(text);
452+
if (i == origSelectionEnd) {
453+
selectionEnd = description.length();
454+
}
455+
456+
if (selectionStart >= 0 && selectionEnd >= 0) {
457+
Selection.setSelection(description, selectionStart, selectionEnd);
458+
}
459+
460+
return description;
461+
}
462+
463+
@Override
464+
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
465+
super.onInitializeAccessibilityEvent(event);
466+
467+
if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED) {
468+
CharSequence text = getTextForAccessibility();
469+
event.setFromIndex(Selection.getSelectionStart(text));
470+
event.setToIndex(Selection.getSelectionEnd(text));
471+
event.setItemCount(text.length());
472+
}
473+
}
474+
402475
private int getCorrectedTokenEnd() {
403476
Editable editable = getText();
404477
int cursorPosition = getSelectionEnd();

0 commit comments

Comments
 (0)