У меня есть TextView
, в котором каждое слово является ClickableSpan
. При щелчке слово становится bold, а словарное слово слова указано в другом TextView. Приложение работает правильно, пока я не сделаю текст в текстовом редакторе TextView. Когда текст сделан выбираемым, определение отображается по щелчку, но слово только жирным шрифтом на двойном щелчке. Текст выбирается двойным щелчком или длительным нажатием (но длительное нажатие не делает слово полужирным).Обращение с кликом для ClickableSpan с выбираемым текстом требует двойного щелчка
Я предполагаю, что проблема связана с тем, что в процессе обработки действий состояние рисования обновляется, но я не смог найти исправление. Я попытался установить TextView
focusable="false"
, но ничего не изменилось. Соответствующий код приведен ниже.
curSpan = new WordSpan(index) {
@Override
public void onClick(View view) {
handleWordClick(index,this); // handles code to display definition
setMarking(true);
view.invalidate();
tvText.invalidate();
}
};
spannableStringBuilder.setSpan(curSpan, totalLength, totalLength + strWord, Spanned.SPAN_COMPOSING);
И определение WordSpan:
class WordSpan extends ClickableSpan
{
int id;
private boolean marking = false;
public WordSpan(int id) {
this.id = id;
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(Color.BLACK);
ds.setUnderlineText(false);
if (marking) {
ds.setTypeface(Typeface.create(myFont,Typeface.BOLD));
}
}
@Override
public void onClick(View v) {}
public void setMarking(boolean m) {
marking = m;
}
}
Настройка метода движения для TextView:
private MovementMethod createMovementMethod (Context context) {
final GestureDetector detector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp (MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapConfirmed (MotionEvent e) {
return true;
}
});
return new ScrollingMovementMethod() {
@Override
public boolean canSelectArbitrarily() {
return true;
}
@Override
public void initialize(TextView widget, Spannable text) {
Selection.setSelection(text, text.length());
}
@Override
public void onTakeFocus(TextView view, Spannable text, int dir) {
if ((dir & (View.FOCUS_FORWARD | View.FOCUS_DOWN)) != 0) {
if (view.getLayout() == null) {
// This shouldn't be null, but do something sensible if it is.
Selection.setSelection(text, text.length());
}
} else {
Selection.setSelection(text, text.length());
}
}
@Override
public boolean onTouchEvent (TextView widget, Spannable buffer, MotionEvent event) {
// check if event is a single tab
boolean isClickEvent = detector.onTouchEvent(event);
// detect span that was clicked
if (isClickEvent) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
WordSpan[] link = buffer.getSpans(off, off, WordSpan.class);
if (link.length != 0) {
// execute click only for first clickable span
// can be a for each loop to execute every one
if (event.getAction() == MotionEvent.ACTION_UP) {
link[0].onClick(widget);
} else if (event.getAction() == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
}
return true;
}
}
// let scroll movement handle the touch
return super.onTouchEvent(widget, buffer, event);
}
};
}
Edit: Я только что открыл новую причуду, которая может помочь в решении. Если я дважды щелкнул, но изменил слова между щелчками (коснитесь одним словом &, тогда будет другое слово быстро), при первом нажатии будет показано определение для этого слова, а на втором касании слово FIRST выделено жирным шрифтом, но выбрано SECOND word (выделено), и определение для ПЕРВОГО слова все еще показано.
Так, например, если я дважды нажмите «первый», а затем «второй», когда я нажимаю «первый» определение для «первого» будет показано ниже, и, когда я прикасаюсь «второй» слово " сначала "выделено полужирным шрифтом, а слово" второе "выделено , но определение не изменяется (по-прежнему отображается определение для " first ").
Привет! Правильно ли я понимаю вопрос. Как обращаться с двойным кликом по TextView с помощью Spannable String с другим текстом, который можно щелкнуть? – GensaGames
Он должен быть одним кликом, а не двойным щелчком. Когда пользователь нажимает на слово, он должен выделять слово и показывать определение. Двойной щелчок ничего не должен делать. –