如何让TextView首字符背景色占满match_parent高度?
问题:TextView首字符背景色占满控件高度需求
我使用的TextView布局代码:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/txt" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:singleLine="true" android:text="TextView for test only" android:textColor="#fff" /> </androidx.constraintlayout.widget.ConstraintLayout>
TextView默认文字为白色,我想将第一个字符改为黑色且背景设为白色,当前实现代码:
TextView txt = (TextView) findViewById(R.id.txt); SpannableStringBuilder sp = new SpannableStringBuilder(txt.getText()); sp.setSpan(new BackgroundColorSpan(Color.WHITE), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); sp.setSpan(new ForegroundColorSpan(Color.BLACK), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); txt.setText(sp);
目前首字符文字颜色修改正常,但背景色仅覆盖文字所在区域,需要让背景色占满TextView的全部高度。
当前效果:
预期效果(Figma制作):
解决方案
BackgroundColorSpan仅会覆盖文本自身的行高区域,要实现背景占满TextView整个高度,需要自定义Span来绘制背景:
1. 自定义FullHeightBackgroundSpan
public class FullHeightBackgroundSpan extends ReplacementSpan { private int mBgColor; public FullHeightBackgroundSpan(int bgColor) { mBgColor = bgColor; } @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { // 返回字符的原始宽度,不改变文本布局 return Math.round(paint.measureText(text, start, end)); } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { // 保存画笔原有颜色 int originalColor = paint.getColor(); // 绘制占满TextView高度的背景矩形 paint.setColor(mBgColor); canvas.drawRect(x, top, x + paint.measureText(text, start, end), bottom, paint); // 恢复画笔颜色,绘制文字 paint.setColor(originalColor); canvas.drawText(text, start, end, x, y, paint); } }
2. 替换原有Span使用自定义类
TextView txt = findViewById(R.id.txt); SpannableStringBuilder sp = new SpannableStringBuilder(txt.getText()); // 使用自定义Span替代BackgroundColorSpan sp.setSpan(new FullHeightBackgroundSpan(Color.WHITE), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); sp.setSpan(new ForegroundColorSpan(Color.BLACK), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); txt.setText(sp);
说明
- 自定义Span的
draw方法中,top和bottom参数对应TextView控件的上下边界,因此绘制的矩形会占满整个控件高度。 - 若TextView高度为
wrap_content,需设置minHeight保证控件有足够高度,否则背景会随文字行高变化。
内容的提问来源于stack exchange,提问作者Taha Sami
相关产品推荐
相关产品推荐

