Skip to content

Commit 80d2aef

Browse files
author
Rafael Dominiquini
committed
Merge remote-tracking branch 'st1hy/develop'
2 parents 64f64f6 + f136a7e commit 80d2aef

File tree

2 files changed

+47
-39
lines changed

2 files changed

+47
-39
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ buildscript {
55
mavenCentral()
66
}
77
dependencies {
8-
classpath 'com.android.tools.build:gradle:2.1.0'
8+
classpath 'com.android.tools.build:gradle:2.1.2'
99
}
1010
}
1111

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

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public boolean isSelectable() {
9090
private TokenSpanWatcher spanWatcher;
9191
private TokenTextWatcher textWatcher;
9292
private ArrayList<T> objects;
93-
private List<TokenCompleteTextView<T>.TokenImageSpan> hiddenSpans;
93+
private List<TokenImageSpan<T>> hiddenSpans;
9494
private TokenDeleteStyle deletionStyle = TokenDeleteStyle._Parent;
9595
private TokenClickStyle tokenClickStyle = TokenClickStyle.None;
9696
private CharSequence prefix = "";
@@ -138,7 +138,7 @@ private void init() {
138138
if (initialized) return;
139139

140140
// Initialise variables
141-
setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
141+
setTokenizer(new CommaTokenizer());
142142
objects = new ArrayList<>();
143143
Editable text = getText();
144144
assert null != text;
@@ -280,6 +280,7 @@ public boolean isTokenRemovable(T token) {
280280
*
281281
* @param p String with the hint
282282
*/
283+
@SuppressWarnings("unused")
283284
public void setPrefix(CharSequence p) {
284285
//Have to clear and set the actual text before saving the prefix to avoid the prefix filter
285286
prefix = "";
@@ -435,7 +436,7 @@ public CharSequence getTextForAccessibility() {
435436
}
436437

437438
//Replace token spans
438-
TokenImageSpan[] tokens = text.getSpans(i, i, TokenImageSpan.class);
439+
TokenImageSpan<T>[] tokens = getSpans(text, i, i);
439440
if (tokens.length > 0) {
440441
TokenImageSpan token = tokens[0];
441442
description = description.append(tokenizer.terminateToken(token.getToken().toString()));
@@ -620,7 +621,7 @@ private boolean deleteSelectedObject(boolean handled) {
620621
Editable text = getText();
621622
if (text == null) return handled;
622623

623-
TokenImageSpan[] spans = text.getSpans(0, text.length(), TokenImageSpan.class);
624+
TokenImageSpan<T>[] spans = getSpans(text, 0, text.length());
624625
for (TokenImageSpan span : spans) {
625626
if (span.view.isSelected()) {
626627
removeSpan(span);
@@ -656,7 +657,7 @@ public boolean onTouchEvent(@NonNull MotionEvent event) {
656657
int offset = getOffsetForPosition(event.getX(), event.getY());
657658

658659
if (offset != -1) {
659-
TokenImageSpan[] links = text.getSpans(offset, offset, TokenImageSpan.class);
660+
TokenImageSpan<T>[] links = getSpans(text, offset, offset);
660661

661662
if (links.length > 0) {
662663
links[0].onClick();
@@ -699,7 +700,7 @@ protected void onSelectionChanged(int selStart, int selEnd) {
699700
Editable text = getText();
700701
if (text != null) {
701702
//Make sure if we are in a span, we select the spot 1 space after the span end
702-
TokenImageSpan[] spans = text.getSpans(selStart, selEnd, TokenImageSpan.class);
703+
TokenImageSpan<T>[] spans = getSpans(text, selStart, selEnd);
703704
for (TokenImageSpan span : spans) {
704705
int spanEnd = text.getSpanEnd(span);
705706
if (selStart <= spanEnd && text.getSpanStart(span) < selStart) {
@@ -737,7 +738,7 @@ public void performCollapse(boolean hasFocus) {
737738
if (text != null && lastLayout != null) {
738739
// Display +x thingy if appropriate
739740
int lastPosition = lastLayout.getLineVisibleEnd(0);
740-
TokenImageSpan[] tokens = text.getSpans(0, lastPosition, TokenImageSpan.class);
741+
TokenImageSpan<T>[] tokens = getSpans(text, 0, lastPosition);
741742
int count = objects.size() - tokens.length;
742743

743744
// Make sure we don't add more than 1 CountSpan
@@ -771,8 +772,7 @@ public void performCollapse(boolean hasFocus) {
771772
// Remove all spans behind the count span and hold them in the hiddenSpans List
772773
// The generic type information is not captured in TokenImageSpan.class so we have
773774
// to perform a cast for the returned spans to coerce them to the proper generic type.
774-
hiddenSpans = new ArrayList<>(Arrays.asList(
775-
(TokenImageSpan[]) text.getSpans(lastPosition + cs.text.length(), text.length(), TokenImageSpan.class)));
775+
hiddenSpans = new ArrayList<>(Arrays.asList(getSpans(text, lastPosition + cs.text.length(), text.length())));
776776
for (TokenImageSpan span : hiddenSpans) {
777777
removeSpan(span);
778778
}
@@ -788,7 +788,7 @@ public void performCollapse(boolean hasFocus) {
788788
}
789789

790790
// Restore the spans we have hidden
791-
for (TokenImageSpan span : hiddenSpans) {
791+
for (TokenImageSpan<T> span : hiddenSpans) {
792792
insertSpan(span);
793793
}
794794
hiddenSpans.clear();
@@ -817,6 +817,11 @@ public void run() {
817817
focusChanging = false;
818818
}
819819

820+
@SuppressWarnings("unchecked")
821+
private TokenImageSpan<T>[] getSpans(Editable text, int start, int length) {
822+
return text.getSpans(start, length, TokenImageSpan.class);
823+
}
824+
820825
@Override
821826
public void onFocusChanged(boolean hasFocus, int direction, Rect previous) {
822827
super.onFocusChanged(hasFocus, direction, previous);
@@ -856,12 +861,12 @@ private SpannableStringBuilder buildSpannableForText(CharSequence text) {
856861
return new SpannableStringBuilder(String.valueOf(sentinel) + tokenizer.terminateToken(text));
857862
}
858863

859-
protected TokenImageSpan buildSpanForObject(T obj) {
864+
protected TokenImageSpan<T> buildSpanForObject(T obj) {
860865
if (obj == null) {
861866
return null;
862867
}
863868
View tokenView = getViewForObject(obj);
864-
return new TokenImageSpan(tokenView, obj, (int) maxTextWidth());
869+
return new TokenImageSpan<>(tokenView, obj, (int) maxTextWidth(), this);
865870
}
866871

867872
@Override
@@ -872,7 +877,7 @@ protected void replaceText(CharSequence text) {
872877
if (selectedObject == null || selectedObject.toString() == null || selectedObject.toString().equals("")) return;
873878

874879
SpannableStringBuilder ssb = buildSpannableForText(text);
875-
TokenImageSpan tokenSpan = buildSpanForObject(selectedObject);
880+
TokenImageSpan<T> tokenSpan = buildSpanForObject(selectedObject);
876881

877882
Editable editable = getText();
878883
int cursorPosition = getSelectionEnd();
@@ -944,6 +949,7 @@ public void addObject(T object) {
944949
*
945950
* @param object object to remove, may be null or not in the view
946951
*/
952+
@SuppressWarnings("unused")
947953
public void removeObject(final T object) {
948954
post(new Runnable() {
949955
@Override
@@ -969,7 +975,7 @@ public void run() {
969975
updateCountSpan();
970976

971977
// If the object is currently visible, remove it
972-
TokenImageSpan[] spans = text.getSpans(0, text.length(), TokenImageSpan.class);
978+
TokenImageSpan<T>[] spans = getSpans(text, 0, text.length());
973979
for (TokenImageSpan span : spans) {
974980
if (span.getToken().equals(object)) {
975981
removeSpan(span);
@@ -1030,7 +1036,7 @@ private void removeSpan(TokenImageSpan span) {
10301036
*/
10311037
private void insertSpan(T object, CharSequence sourceText) {
10321038
SpannableStringBuilder ssb = buildSpannableForText(sourceText);
1033-
TokenImageSpan tokenSpan = buildSpanForObject(object);
1039+
TokenImageSpan<T> tokenSpan = buildSpanForObject(object);
10341040

10351041
Editable editable = getText();
10361042
if (editable == null) return;
@@ -1082,7 +1088,7 @@ private void insertSpan(T object) {
10821088
insertSpan(object, spanString);
10831089
}
10841090

1085-
private void insertSpan(TokenImageSpan span) {
1091+
private void insertSpan(TokenImageSpan<T> span) {
10861092
insertSpan(span.getToken());
10871093
}
10881094

@@ -1102,7 +1108,7 @@ public void run() {
11021108
if (text == null) return;
11031109

11041110
// Get all spans in the EditText and remove them
1105-
TokenImageSpan[] spans = text.getSpans(0, text.length(), TokenImageSpan.class);
1111+
TokenImageSpan<T>[] spans = getSpans(text, 0, text.length());
11061112
for (TokenImageSpan span : spans) {
11071113
removeSpan(span);
11081114

@@ -1172,55 +1178,57 @@ private void clearSelections() {
11721178
Editable text = getText();
11731179
if (text == null) return;
11741180

1175-
TokenImageSpan[] tokens = text.getSpans(0, text.length(), TokenImageSpan.class);
1181+
TokenImageSpan<T>[] tokens = getSpans(text, 0, text.length());
11761182
for (TokenImageSpan token : tokens) {
11771183
token.view.setSelected(false);
11781184
}
11791185
invalidate();
11801186
}
11811187

1182-
protected class TokenImageSpan extends ViewSpan implements NoCopySpan {
1188+
protected static class TokenImageSpan<T> extends ViewSpan implements NoCopySpan {
11831189
private T token;
1190+
final TokenCompleteTextView<T> parent;
11841191

1185-
public TokenImageSpan(View d, T token, int maxWidth) {
1192+
public TokenImageSpan(View d, T token, int maxWidth, TokenCompleteTextView<T> parent) {
11861193
super(d, maxWidth);
11871194
this.token = token;
1195+
this.parent = parent;
11881196
}
11891197

11901198
public T getToken() {
11911199
return this.token;
11921200
}
11931201

11941202
public void onClick() {
1195-
Editable text = getText();
1203+
Editable text = parent.getText();
11961204
if (text == null) return;
11971205

1198-
switch (tokenClickStyle) {
1206+
switch (parent.tokenClickStyle) {
11991207
case Select:
12001208
case SelectDeselect:
12011209

12021210
if (!view.isSelected()) {
1203-
clearSelections();
1211+
parent.clearSelections();
12041212
view.setSelected(true);
12051213
break;
12061214
}
12071215

1208-
if (tokenClickStyle == TokenClickStyle.SelectDeselect || !isTokenRemovable(token)) {
1216+
if (parent.tokenClickStyle == TokenClickStyle.SelectDeselect || !parent.isTokenRemovable(token)) {
12091217
view.setSelected(false);
1210-
invalidate();
1218+
parent.invalidate();
12111219
break;
12121220
}
12131221
//If the view is already selected, we want to delete it
12141222
case Delete:
1215-
if (isTokenRemovable(token)) {
1216-
removeSpan(this);
1223+
if (parent.isTokenRemovable(token)) {
1224+
parent.removeSpan(this);
12171225
}
12181226
break;
12191227
case None:
12201228
default:
1221-
if (getSelectionStart() != text.getSpanEnd(this) + 1) {
1229+
if (parent.getSelectionStart() != text.getSpanEnd(this) + 1) {
12221230
//Make sure the selection is not in the middle of the span
1223-
setSelection(text.getSpanEnd(this) + 1);
1231+
parent.setSelection(text.getSpanEnd(this) + 1);
12241232
}
12251233
}
12261234
}
@@ -1237,8 +1245,8 @@ private class TokenSpanWatcher implements SpanWatcher {
12371245
@SuppressWarnings("unchecked cast")
12381246
@Override
12391247
public void onSpanAdded(Spannable text, Object what, int start, int end) {
1240-
if (what instanceof TokenCompleteTextView<?>.TokenImageSpan && !savingState && !focusChanging) {
1241-
TokenImageSpan token = (TokenImageSpan) what;
1248+
if (what instanceof TokenImageSpan && !savingState && !focusChanging) {
1249+
TokenImageSpan<T> token = (TokenImageSpan) what;
12421250
objects.add(token.getToken());
12431251

12441252
if (listener != null)
@@ -1249,8 +1257,8 @@ public void onSpanAdded(Spannable text, Object what, int start, int end) {
12491257
@SuppressWarnings("unchecked cast")
12501258
@Override
12511259
public void onSpanRemoved(Spannable text, Object what, int start, int end) {
1252-
if (what instanceof TokenCompleteTextView<?>.TokenImageSpan && !savingState && !focusChanging) {
1253-
TokenImageSpan token = (TokenImageSpan) what;
1260+
if (what instanceof TokenImageSpan && !savingState && !focusChanging) {
1261+
TokenImageSpan<T> token = (TokenImageSpan) what;
12541262
if (objects.contains(token.getToken())) {
12551263
objects.remove(token.getToken());
12561264
}
@@ -1288,7 +1296,7 @@ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
12881296
start -= 1;
12891297
}
12901298

1291-
TokenImageSpan[] spans = text.getSpans(start, end, TokenImageSpan.class);
1299+
TokenImageSpan<T>[] spans = getSpans(text, start, end);
12921300

12931301
//NOTE: I'm not completely sure this won't cause problems if we get stuck in a text changed loop
12941302
//but it appears to work fine. Spans will stop getting removed if this breaks.
@@ -1481,8 +1489,8 @@ public String toString() {
14811489
}
14821490

14831491
@SuppressWarnings("hiding")
1484-
public static final Parcelable.Creator<SavedState> CREATOR
1485-
= new Parcelable.Creator<SavedState>() {
1492+
public static final Creator<SavedState> CREATOR
1493+
= new Creator<SavedState>() {
14861494
public SavedState createFromParcel(Parcel in) {
14871495
return new SavedState(in);
14881496
}
@@ -1509,11 +1517,11 @@ public boolean canDeleteSelection(int beforeLength) {
15091517
int startSelection = beforeLength == 1 ? getSelectionStart() : endSelection - beforeLength;
15101518

15111519
Editable text = getText();
1512-
TokenImageSpan[] spans = text.getSpans(0, text.length(), TokenImageSpan.class);
1520+
TokenImageSpan<T>[] spans = getSpans(text, 0, text.length());
15131521

15141522
// Iterate over all tokens and allow the deletion
15151523
// if there are no tokens not removable in the selection
1516-
for (TokenImageSpan span : spans) {
1524+
for (TokenImageSpan<T> span : spans) {
15171525
int startTokenSelection = text.getSpanStart(span);
15181526
int endTokenSelection = text.getSpanEnd(span);
15191527

0 commit comments

Comments
 (0)