我有一個TextView
其中每個單詞是ClickableSpan
。單擊時,單詞變成加粗並且單詞的字典定義顯示在另一個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);
}
};
}
編輯: 我剛剛發現了一個新的怪癖,可以解決幫助。如果我雙擊但單擊之間改變單詞(點擊一個單詞&,然後快速選擇另一個單詞),在第一次敲擊時顯示該單詞的定義,在第二次敲擊時,第一個單詞顯示爲粗體,但第二個單詞被選中(突出顯示)並且第一個字的定義仍然顯示。
因此,舉例來說,如果我槍王「第一」,然後「第二」,當我點擊 「第一」的定義爲「第一」將顯示,當我觸摸 「第二個」一字「第一個「是粗體字,」second「字是突出顯示的 ,但定義不變(仍然顯示 」第一個「的定義)。
嘿!我是否正確理解問題。如何處理帶有不同可點擊文本的Spannable String的TextView雙擊? – GensaGames
它應該是單擊而不是雙擊。當用戶點擊單詞時,應該加粗單詞並顯示定義。雙擊不應該做任何事情。 –