我知道如何在textview中给文本加下划线。但是,如何在带有不同颜色的文本下划线呢?
下划线可以通过以下方式完成:
TextView t = (TextView) findViewById(R.id.textview);
t.setPaintFlags(t.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
t.setText("Underline Text");
假设我的textcolor是黑色的,而我想在蓝色下划线,怎么做?
提前致谢。
最佳答案
我有同样的问题,在阅读其他关于EditText
的文章时,我偶然发现了Layout类。它通过使用 Canvas 手动绘制下划线来提供实现此目标所需的一切。
首先,我定义了自定义属性,以便在XML布局文件中轻松自定义
<declare-styleable name="UnderlinedTextView" >
<attr name="underlineHeight" format="dimension" />
<attr name="underlineOffset" format="dimension" />
<attr name="underlineColor" format="color" />
<attr name="underLinePosition" format="enum">
<enum name="baseline" value="0" />
<enum name="below" value="1" />
</attr>
</declare-styleable>
还有一个自定义的TextView
类 class UnderlinedTextView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : androidx.appcompat.widget.AppCompatTextView(context, attrs, defStyleAttr) {
@Retention(AnnotationRetention.SOURCE)
@IntDef(POSITION_BASELINE, POSITION_BELOW)
annotation class UnderLinePosition {
companion object {
const val POSITION_BASELINE = 0
const val POSITION_BELOW = 1
}
}
private val linePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
style = Paint.Style.FILL
}
var lineColor: Int
get() = linePaint.color
set(value) {
if (linePaint.color != value) {
linePaint.color = value
invalidate()
}
}
var lineHeight: Float
get() = linePaint.strokeWidth
set(value) {
if (linePaint.strokeWidth != value) {
linePaint.strokeWidth = value
updateSpacing()
}
}
var lineTopOffset = 0F
set(value) {
if (field != value) {
field = value
updateSpacing()
}
}
@UnderLinePosition
var linePosition = POSITION_BASELINE
private val rect = Rect()
private var internalAdd: Float = lineSpacingExtra
private inline val extraSpace
get() = lineTopOffset + lineHeight
init {
val density = context.resources.displayMetrics.density
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.UnderlinedTextView, defStyleAttr, 0)
lineColor = typedArray.getColor(R.styleable.UnderlinedTextView_underlineColor, currentTextColor)
lineTopOffset = typedArray.getDimension(R.styleable.UnderlinedTextView_underlineOffset, 0f)
lineHeight = typedArray.getDimension(R.styleable.UnderlinedTextView_underlineHeight, density * 1)
linePosition = typedArray.getInt(R.styleable.UnderlinedTextView_underLinePosition, POSITION_BASELINE)
typedArray.recycle()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
setMeasuredDimension(measuredWidth, measuredHeight + (extraSpace + 0.5f).toInt())
}
override fun onDraw(canvas: Canvas?) {
canvas?.takeIf { !text.isNullOrEmpty() }?.let {
val count = lineCount
val layout = layout
var xStart: Float
var xStop: Float
var yStart: Float
var firstCharInLine: Int
var lastCharInLine: Int
var lastLine: Boolean
var offset: Int
val lineSpacing = lineSpacingExtra * lineSpacingMultiplier
for (i in 0 until count) {
val baseline = getLineBounds(i, rect)
lastLine = i == count - 1
offset = if (lastLine) 0 else 1
firstCharInLine = layout.getLineStart(i)
lastCharInLine = layout.getLineEnd(i)
xStart = layout.getPrimaryHorizontal(firstCharInLine)
xStop = layout.getPrimaryHorizontal(lastCharInLine - offset)
yStart = when (linePosition) {
POSITION_BASELINE -> baseline + lineTopOffset
POSITION_BELOW -> (rect.bottom + lineTopOffset) - if (lastLine) 0F else lineSpacing
else -> throw NotImplementedError("")
}
canvas.drawRect(xStart, yStart, xStop, yStart + lineHeight, linePaint)
}
}
super.onDraw(canvas)
}
private fun updateSpacing() {
setLineSpacing(internalAdd, 1f)
}
override fun setLineSpacing(add: Float, mult: Float) {
internalAdd = add
super.setLineSpacing(add + extraSpace, 1f)
}
}
然后它的用法很简单<some.package.UnderlinedTextView
android:id="@+id/tvTest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:gravity="center"
android:text="This is a demo text"
android:textSize="16sp"
app:underlineColor="#ffc112ef"
app:underlineHeight="3dp"/>
最终结果关于android - 如何在TextView中用与文本不同的颜色对文本加下划线?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19046614/