我有一个ImageSpan一段文字里面。我注意到周围的文本总是绘制在文本行的底部——更准确地说,文本行的大小随着图像的增长而增长,但文本的基线不会向上移动。当图像明显大于文本大小时,效果就相当难看。
Here is a sample, the outline shows bounds of the TextView
:
我试图让周围的文本相对于所显示的图像垂直居中。这是相同的示例,蓝色文本显示所需的位置:
以下是我受到的约束:
- 我无法使用复合绘图。图像必须能够在文字之间显示。
- 根据内容,文本可能是多行的。我对此无法控制。
- 我的图像比周围的文本大,我无法缩小它们的大小。虽然上面的示例图像比实际图像大(以演示当前行为),但实际图像仍然足够大,因此这个问题很明显。
我尝试过使用android:gravity="center_vertical"
TextView 上的属性,但这没有任何效果。我相信这只是垂直居中文本lines,但在文本行内,文本仍然绘制在底部。
我当前的思路是创建一个自定义跨度,根据行高和当前文本大小来移动文本的基线。这个跨度将包含整个文本,我必须计算与ImageSpan
这样我也可以避免移动图像。这听起来相当令人畏惧,我希望有人能提出另一种方法。
感谢任何和所有的帮助!
我的答案调整了第一个答案。其实上面两种方法我都试过了,我不认为它们是真正的中心垂直。如果将可绘制对象放置在两者之间,它将使可绘制对象更加居中ascent
and descent
, 而不是top
and bottom
。对于第二个答案,它将可绘制对象的中心与文本的基线对齐,而不是该文本的中心。这是我的解决方案:
public class CenteredImageSpan extends ImageSpan {
private WeakReference<Drawable> mDrawableRef;
public CenteredImageSpan(Context context, final int drawableRes) {
super(context, drawableRes);
}
@Override
public int getSize(Paint paint, CharSequence text,
int start, int end,
Paint.FontMetricsInt fm) {
Drawable d = getCachedDrawable();
Rect rect = d.getBounds();
if (fm != null) {
Paint.FontMetricsInt pfm = paint.getFontMetricsInt();
// keep it the same as paint's fm
fm.ascent = pfm.ascent;
fm.descent = pfm.descent;
fm.top = pfm.top;
fm.bottom = pfm.bottom;
}
return rect.right;
}
@Override
public void draw(@NonNull Canvas canvas, CharSequence text,
int start, int end, float x,
int top, int y, int bottom, @NonNull Paint paint) {
Drawable b = getCachedDrawable();
canvas.save();
int drawableHeight = b.getIntrinsicHeight();
int fontAscent = paint.getFontMetricsInt().ascent;
int fontDescent = paint.getFontMetricsInt().descent;
int transY = bottom - b.getBounds().bottom + // align bottom to bottom
(drawableHeight - fontDescent + fontAscent) / 2; // align center to center
canvas.translate(x, transY);
b.draw(canvas);
canvas.restore();
}
// Redefined locally because it is a private member from DynamicDrawableSpan
private Drawable getCachedDrawable() {
WeakReference<Drawable> wr = mDrawableRef;
Drawable d = null;
if (wr != null)
d = wr.get();
if (d == null) {
d = getDrawable();
mDrawableRef = new WeakReference<>(d);
}
return d;
}
}
我也重写一下getSize
保持drawable的FontMetrics与其他文本相同,否则父视图将无法正确包装内容。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)