Android textview наброски текста - PullRequest
73 голосов
/ 06 июля 2010

Есть ли простой способ, чтобы текст мог иметь черный контур? У меня есть текстовые просмотры, которые будут разных цветов, но некоторые цвета не очень хорошо отображаются на моем фоне, поэтому мне было интересно, есть ли простой способ получить черный контур или что-то еще, что будет работать? Я бы предпочел не создавать пользовательский вид и создавать холст и тому подобное.

Ответы [ 15 ]

1 голос
/ 14 февраля 2019

Я хочу добавить решение для решения проблемы производительности. Например, ответ @YGHM и нескольких других делает свою работу, но это вызывает бесконечный вызов onDraw, потому что setTextColor вызывает invalidate(). Таким образом, чтобы решить эту проблему, вам также нужно переопределить invalidate() и добавить переменную isDrawing, которую вы установите в true, когда onDraw() находится в процессе и рисует с обводкой. invalidate вернется, если переменная true.

override fun invalidate() {
    if (isDrawing) return
    super.invalidate()
  }

Ваш onDraw будет выглядеть так:

override fun onDraw(canvas: Canvas) {
    if (strokeWidth > 0) {
      isDrawing = true
      val textColor = textColors.defaultColor
      setTextColor(strokeColor)
      paint.strokeWidth = strokeWidth
      paint.style = Paint.Style.STROKE
      super.onDraw(canvas)
      setTextColor(textColor)
      paint.strokeWidth = 0f
      paint.style = Paint.Style.FILL
      isDrawing = false
      super.onDraw(canvas)
    } else {
      super.onDraw(canvas)
    }
  }
1 голос
/ 09 июля 2018

Я нашел простой способ обвести представление без наследования от TextView . Я написал простую библиотеку, в которой для выделения текста используется Android Spannable . Это решение дает возможность выделить только часть текста.

Я уже ответил на тот же вопрос ( ответ )

Класс:

class OutlineSpan(
        @ColorInt private val strokeColor: Int,
        @Dimension private val strokeWidth: Float
): ReplacementSpan() {

    override fun getSize(
            paint: Paint,
            text: CharSequence,
            start: Int,
            end: Int,
            fm: Paint.FontMetricsInt?
    ): Int {
        return paint.measureText(text.toString().substring(start until end)).toInt()
    }


    override fun draw(
            canvas: Canvas,
            text: CharSequence,
            start: Int,
            end: Int,
            x: Float,
            top: Int,
            y: Int,
            bottom: Int,
            paint: Paint
    ) {
        val originTextColor = paint.color

        paint.apply {
            color = strokeColor
            style = Paint.Style.STROKE
            this.strokeWidth = this@OutlineSpan.strokeWidth
        }
        canvas.drawText(text, start, end, x, y.toFloat(), paint)

        paint.apply {
            color = originTextColor
            style = Paint.Style.FILL
        }
        canvas.drawText(text, start, end, x, y.toFloat(), paint)
    }

}

Библиотека: OutlineSpan

1 голос
/ 10 января 2017

Я создал библиотеку на основе ответа Нумана Ханифа с некоторыми дополнениями.Например, исправляя ошибку, которая вызывала косвенный бесконечный цикл при вызовах View.invalidate ().

OTOH, библиотека также поддерживает выделенный текст в виджетах EditText, поскольку это была моя настоящая цель, и ей нужно было немного большеработа, чем TextView.

Вот ссылка на мою библиотеку: https://github.com/biomorgoth/android-outline-textview

Спасибо Нуману Ханифу за первоначальную идею о решении!

1 голос
/ 13 августа 2016

MagicTextView очень полезен для создания штрихового шрифта, но в моем случае это вызывает ошибку, такую ​​как this , эта ошибка вызвана дублированием атрибутов фона, которые устанавливаются MagicTextView

, поэтому вам нужно отредактироватьattrs.xml и MagicTextView.java

attrs.xml

<attr name="background" format="reference|color" />
 ↓
<attr name="mBackground" format="reference|color" />

MagicTextView.java 88: 95

if (a.hasValue(R.styleable.MagicTextView_mBackground)) {
Drawable background = a.getDrawable(R.styleable.MagicTextView_mBackground);
if (background != null) {
    this.setBackgroundDrawable(background);
} else {
    this.setBackgroundColor(a.getColor(R.styleable.MagicTextView_mBackground, 0xff000000));
}
}
1 голос
/ 06 июля 2010

То есть, вы хотите обвести текст?К сожалению, не существует простого способа сделать это с помощью стиля.Вам придется создать другой вид и разместить текстовое представление поверх него, сделав родительский вид (тот, на котором он расположен) всего на несколько пикселей больше - это должно создать контур.

...