gpt4 book ai didi

Android ClickableSpan 不改变样式 onclick

转载 作者:行者123 更新时间:2023-11-29 17:17:59 27 4
gpt4 key购买 nike

我有一个 TextView,其中所有单词都可以单独点击。我想从每一个没有风格的词开始。单击一个词后,该词应变为并保持下划线。我能够清除默认下划线,但点击后没有任何反应。 (我正在捕获甚至处理点击,但我无法更改 Span 样式)。

相关代码如下。预先感谢您的帮助。

自定义 ClickableSpan:

class WordSpan extends ClickableSpan {
private TextPaint textpaint;
public boolean clicked = false;

@Override
public void updateDrawState(TextPaint ds) {
textpaint = ds;
ds.setUnderlineText(false);

if (clicked)
ds.setUnderlineText(true);
}

@Override
public void onClick(View v) {}

public void setClicked(boolean c) {
clicked = c;
updateDrawState(textpaint);
}
}

我从 onCreate() 解析一个 txt 文件并将每个单词添加到 TextView。在这个解析循环中,我有以下代码:

  SpannableString ss = new SpannableString(word.toString());

WordSpan clickableSpan = new WordSpan() {
@Override
public void onClick(View view) {
setClicked(true);
view.invalidate();
}};

ss.setSpan(clickableSpan, 0, word.toString().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

tvText.append(ss);
tvText.append(" ");
}

tvText.setMovementMethod(LinkMovementMethod.getInstance());

最佳答案

要使单个单词可点击,您必须向 spannable 字符串添加多个可点击的 span。例如,要在单个 Textview 中单独点击“foo”和“bar”,您必须添加两个可点击的 span,一个用于“foo”,另一个用于“bar”,并将它们添加到 spannable 字符串中。

在示例中,为了简单起见,我使用空格拆分了字符串,而且您还必须为单击跨度编写逻辑。

删除下划线的可点击范围。此外,您可以在单击时配置背景和文本颜色。如果您不打算使用它,可以将其删除。

import android.text.TextPaint;
import android.text.style.ClickableSpan;

public abstract class TouchableSpan extends ClickableSpan {
private boolean mIsPressed;
private int mPressedBackgroundColor;
private int mNormalTextColor;
private int mPressedTextColor;
private int mBackgroundColor;

public TouchableSpan(int normalTextColor,int backgroundColor, int pressedTextColor, int pressedBackgroundColor) {
mBackgroundColor = backgroundColor;
mNormalTextColor = normalTextColor;
mPressedTextColor = pressedTextColor;
mPressedBackgroundColor = pressedBackgroundColor;
}

public void setPressed(boolean isSelected) {
mIsPressed = isSelected;
}

@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(mIsPressed ? mPressedTextColor : mNormalTextColor);
ds.bgColor = mIsPressed ? mPressedBackgroundColor : mBackgroundColor;
ds.setUnderlineText(!mIsPressed);
}
}

创建一个 LinkMovementMethod 来处理您的 Span。如果您删除颜色规定,您也可以更改它

import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.view.MotionEvent;
import android.widget.TextView;

public class LinkTouchMovementMethod extends LinkMovementMethod {

private TouchableSpan mPressedSpan;

@Override
public boolean onTouchEvent(TextView textView, Spannable spannable, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mPressedSpan = getPressedSpan(textView, spannable, event);
if (mPressedSpan != null) {
mPressedSpan.setPressed(true);
Selection.setSelection(spannable, spannable.getSpanStart(mPressedSpan),
spannable.getSpanEnd(mPressedSpan));
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
TouchableSpan touchedSpan = getPressedSpan(textView, spannable, event);
if (mPressedSpan != null && touchedSpan != mPressedSpan) {
mPressedSpan.setPressed(false);
mPressedSpan = null;
Selection.removeSelection(spannable);
}
} else {
if (mPressedSpan != null) {
mPressedSpan.setPressed(false);
super.onTouchEvent(textView, spannable, event);
}
mPressedSpan = null;
Selection.removeSelection(spannable);
}
return true;
}

private TouchableSpan getPressedSpan(TextView textView, Spannable spannable, MotionEvent event) {

int x = (int) event.getX();
int y = (int) event.getY();

x -= textView.getTotalPaddingLeft();
y -= textView.getTotalPaddingTop();

x += textView.getScrollX();
y += textView.getScrollY();

Layout layout = textView.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);

TouchableSpan[] link = spannable.getSpans(off, off, TouchableSpan.class);
TouchableSpan touchedSpan = null;
if (link.length > 0) {
touchedSpan = link[0];
}
return touchedSpan;
}

}

那么您可以通过以下方式使用它:

TextView textView = (TextView)findViewById(R.id.hello_world);
String fooBar = "asdfasdfasdfasf asdfasfasfasd";
String[] clickSpans = fooBar.split(" ");
int clickSpanLength = clickSpans.length;
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
int totalLength = 0;
int normalColor = getResources().getColor(android.R.color.black);
int clickColor = getResources().getColor(android.R.color.holo_blue_bright);
String separator = " , ";
int separatorLength = separator.length();
for (int i = 0; i < clickSpanLength; i++) {
int currentWordLength = clickSpans[i].length();
spannableStringBuilder.append(clickSpans[i]);
if (i < clickSpanLength - 1) {
spannableStringBuilder.append(" , ");
}

spannableStringBuilder.setSpan(new TouchableSpan(normalColor, Color.TRANSPARENT, clickColor, Color.TRANSPARENT) {
@Override
public void onClick(View widget) {

}
}, totalLength, totalLength + currentWordLength, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
totalLength = totalLength + currentWordLength + separatorLength;
}

textView.setText(spannableStringBuilder);
textView.setMovementMethod(new LinkTouchMovementMethod());

关于Android ClickableSpan 不改变样式 onclick,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37977148/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com