如何自定义使用 OnDraw()。

huangapple go评论83阅读模式
英文:

how to customize use of OnDraw()

问题

我想在自定义的textView中使一部分文字的删除线颜色与文字颜色不同。请问应该如何做?目前所有的textView都有删除线。以下是自定义TextView类的仅包含OnDraw方法的代码:

public class CustomTextView extends TextView {

    @Override
    protected void onDraw(Canvas canvas) {
        Paint paint = new Paint();
        paint.setColor(color);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrikeThruText(true);
        paint.setStrokeWidth(6.0f);
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);
        super.onDraw(canvas);
        float width = getWidth();
        float height = getHeight();
        canvas.drawLine(0, height / 2, width, height / 2, paint);
    }

如果在我的TextView中有文字“Hello World”,我只想让“Hello”这部分有删除线,而不是整个textView都有删除线。我已经陷在这个问题上很长时间了,任何帮助将不胜感激。

英文:

I want to setStrikeThrough of a different color than the textcolor on just 1 word in my Custom textView. How do I do that. At the moment all of my textView gets Strikethrough'd. Here is the code for the Custom TextView Class with just the OnDraw method.

public class CustomTextView extends TextView {

@Override
protected void onDraw(Canvas canvas) {
    Paint paint = new Paint();
    paint.setColor(color);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrikeThruText(true);
    paint.setStrokeWidth(6.0f);
    paint.setFlags(Paint.ANTI_ALIAS_FLAG);
    super.onDraw(canvas);
    float width = getWidth();
    float height = getHeight();
    canvas.drawLine(0, height / 2, width, height / 2, paint);
}

If I have "Hello World" in my TextView, I just want the "Hello" to have a strikethrough rather than the whole textview to have it. I have been stuck at this for a very long time now any help would be gladly accepted

答案1

得分: 1

如果您想要为单个单词添加删除线,最好使用StrikethroughSpan,而无需覆盖onDraw方法甚至使用自定义的TextView。

您可以定义单词字符的起始索引和单词字符的结束索引,如下所示:

final StrikethroughSpan span = new StrikethroughSpan();
final Spannable spannable = (Spannable)yourTextView.getText();
spannable.setSpan(span, WORD_START_INDEX, WORD_END_INDEX, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
yourTextView.setText(spannable);

另外需要注意的是,您不应该在onDraw方法内部创建新的类实例,比如在您的例子中的Paint paint = new Paint(),这会直接在onDraw调用中创建新的实例。
Lint应该会对此进行警告。onDraw方法可能每秒钟被调用数百次,因此会创建数百个新实例并占用内存。避免在诸如onDraw、onMeasure或任何可能在短时间内被调用数百次的方法内部始终创建新的类实例。请始终检查lint警告(黄色标记)。

英文:

If you want a strike through for a single word, then would be better to use a StrikethroughSpan, without needing to override the onDraw method or even using a custom TextView at all.

You can define a word character start index, and word character end index, such as next:

final StrikethroughSpan span = new StrikethroughSpan();
final Spannable spannable = (Spannable)yourTextView.getText();
spannable.setSpan(span, WORD_START_INDEX, WORD_END_INDEX, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
yourTextView.setText(spannable);

As a side note, notice that you should never create new class instances inside the onDraw method, such as in your example Paint paint = new Paint(), which you are creating right inside the onDraw call.
Lint should already warn you about this. The onDraw method can be called hundreds of times per second, and therefore create hundreds of new instances and filling up the memory. Avoid always to create new class instances inside methods such as onDraw, onMeasure, or any other method that can be called hundreds of times in a short period. Always check the lint warnings (yellow marks).

huangapple
  • 本文由 发表于 2020年9月26日 20:05:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/64077472.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定