为部分 TextView 设置可绘制背景

Set drawable background for a portion of TextView

我在 Textview 中为 android:background 属性创建了一个自定义可绘制对象。 但是我只想要 TextView 的某个部分而不是整个 TextView

的可绘制背景

到目前为止完成的工作:

Objective: 我想达到这样的效果(即只为 substring(1,2) 文本设置背景):

我是这样取得目前成绩的:

overline.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:bottom="-2dp"
        android:left="-2dp"
        android:right="-2dp"
        android:top="1dp">
        <shape android:shape="rectangle">
            <stroke
                android:width="1dp"
                android:color="#030310" />
        </shape>
    </item>
</layer-list>

layout.xml

<TextView
    android:id="@+id/myTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/overline"
    android:textColor="#030310"
    android:text="Hello"/>

这是我到目前为止尝试过的方法:

SpannableString ss = new SpannableString("Hello");

Drawable d = ContextCompat.getDrawable(((MainActivity) getActivity()).getApplicationContext(), R.drawable.overline);
d.setBounds(0, 0, 30, 30);

ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
ss.setSpan(span, 1, 2, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

myTextView.setText(ss);

我不太了解 ImageSpan,因此这是我在尝试上面的代码后得到的结果(我在从 MainActivity 加载的 Fragment 中编写这段代码),

不幸的是,据我所知,没有开箱即用的 Android 解决方案来满足您的需求。您在查看 span 方面进展顺利,但 span 提供了对底层 TextPaint 的访问,并且只能真正执行 TextPaint 可以执行的操作。例外情况是 ReplacementSpan,它会完全替换跨区文本。您的 ImageSpan 是一个 ReplacementSpan,因此矩形会替换所有文本并且不会像预期的那样重叠。

有多种方法可以完成您的要求,但 Drawing a rounded corner background on text 中概述了我更喜欢的一种。这将是一个通用的解决方案,但您需要对其进行调整以使圆形背景成为可绘制的上划线。

如果这对您来说太过分了,并且您的文本视图足够简单并且您知道要绘制的线条不会越过线条边界,您还可以查看 this.

您还可以创建一个 View 的简单 2dp 宽度,并根据需要用背景覆盖字母并以编程方式移动它。自定义 View 也可以覆盖所有文本,您可以在视图的 onDraw() 函数中画线。 TextView StaticLayout 可以帮助确定应在自定义视图中的何处绘制线条。

我相信如果您搜索的话,网上还有其他可用的解决方案。