由于Android's Roboto font doesn't seem to contain arrow glyphs,如果可能,这将导致它显示后备字体中的字符(尽管我找不到此行为的文档)。我猜您设备上的“后备”箭头出于某种原因位于基线上。
但是,有一个技巧可能对您有所帮助:您可以包含特殊字符的图像并将图像插入到输出文本中。
首先,在res/drawable 中添加一个新的Drawable 资源文件(ic_arrow.xml),并将其复制粘贴到其中:
<vector android:alpha="0.78" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M3,12L21.5,12"
android:strokeColor="#000000" android:strokeWidth="1"/>
<path android:fillColor="#FF000000" android:pathData="M21,12L17,8"
android:strokeColor="#000000" android:strokeWidth="1"/>
<path android:fillColor="#FF000000" android:pathData="M21,12L17,16"
android:strokeColor="#000000" android:strokeWidth="1"/>
</vector>
现在,我们需要将箭头图像嵌入到可以在 TextView 中显示的 SpannableString 中。我将引导您完成完成此任务所需的(令人惊讶的许多)代码行:
-
获取 Drawable 资源,以便我们在显示之前将其调整为正确的大小。
Drawable arrow = ContextCompat.getDrawable(this, R.drawable.ic_arrow);
-
弄清楚箭头需要多大,based on the font
metrics。
Float ascent = textView.getPaint().getFontMetrics().ascent;
-
这是负面的 (for reasons),所以让它成为正面的。
int h = (int) -ascent;
-
最后,我们可以设置 Drawable 的边界以匹配文本
大小。
arrow.setBounds(0,0,h,h);
-
接下来,创建一个使用我们的文本初始化的 SpannableString。我只是在这里使用* 作为占位符,但它可以是任何字符(或空格)。如果您打算将不同的位与多个箭头图像连接在一起,请为此使用SpannableStringBuilder。
SpannableString stringWithImage = new SpannableString("A*B");
-
现在,我们终于可以将图像插入到 span 中了(使用新的
ImageSpan 与我们的“箭头”图像,aligned with the baseline)。
1 和 2 是从零开始和结束的索引(告诉
插入图像),SPAN_EXCLUSIVE_EXCLUSIVE 表示
the span doesn't expand to include inserted text.
stringWithImage.setSpan(new ImageSpan(arrow, DynamicDrawableSpan.ALIGN_BASELINE), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-
最后,我们可以显示文字(包括自定义箭头图片):
textView.setText(stringWithImage);
总之,代码应该是这样的。
TextView textView = findViewById(R.id.my_text_view);
Drawable arrow = ContextCompat.getDrawable(this, R.drawable.ic_arrow);
Float ascent = textView.getPaint().getFontMetrics().ascent;
int h = (int) -ascent;
arrow.setBounds(0,0,h,h);
SpannableString stringWithImage = new SpannableString("A*B");
stringWithImage.setSpan(new ImageSpan(arrow, DynamicDrawableSpan.ALIGN_BASELINE), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(stringWithImage);
我希望 Android 有更好的方法来做这种事情,但至少可以以某种方式完成。生成的 TextView 应如下所示: