调整围绕ImageSpan中心垂直文本 [英] Align text around ImageSpan center vertical

查看:2246
本文介绍了调整围绕ImageSpan中心垂直文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个<一个href="https://developer.android.com/reference/android/text/style/ImageSpan.html"><$c$c>ImageSpan里面的一段文字中。我所注意到的是,周围的文字总是画在文本行的底部 - 更precise,文本行的规模增长与图像,但文本的基线没有向上移动。当图像是明显比文本大小越大,其效果是相当不雅观。

I have an ImageSpan inside of a piece of text. What I've noticed is that the surrounding text is always drawn at the bottom of the text line -- to be more precise, the size of the text line grows with the image but the baseline of the text does not shift upward. When the image is noticeably larger than the text size, the effect is rather unsightly.

下面是一个简单的,轮廓显示界的的TextView

Here is a sample, the outline shows bounds of the TextView:

我想有周围的文本来就被显示的图像垂直居中。下面是蓝色文字相同的样品展示所需要的位置:

I am trying to have the surrounding text be centered vertically with respect to the image being displayed. Here is the same sample with blue text showing the desired location:

下面是我的约束约束:

  • 我不能使用的化合物可绘制。图像必须能够被字之间所示。
  • 文本可以为多视情节。我有过这个没有控制权。
  • 我不能降低图像的大小。虽然上述样本图像是比实际图像放大(以展示当前行为),实际图像是仍然足够大,这个问题是显着的。

我已经使用 Android的尝试:重力对TextView的=center_vertical属性,但是这并没有产生任何影响。我相信这只是垂直居中文本的的,但文本行中的文本仍然是绘制在底部。

I've tried using the android:gravity="center_vertical" attribute on the TextView, but this does not have any effect. I believe this just vertically centers the text lines, but within the text line the text is still drawn at the bottom.

我目前的思路是创建一个自定义的范围,从而改变根据线路的高度和当前的文本大小的文本的基线。这个跨度将涵盖整个文本,我将不得不计算与 ImageSpan 路口Š这样我就可以避开移动的影像。这听起来相当艰巨,我希望有人可以建议另一种方法。

My current train of thought is to create a custom span that shifts the baseline of the text based on the height of the line and the current text size. This span would encompass the entire text, and I would have to compute the intersection with the ImageSpans so I can avoid shifting the images as well. This sounds rather daunting and I'm hoping someone can suggest another approach.

任何及所有的帮助是AP preciated!

Any and all help is appreciated!

推荐答案

这可能是有点晚了,但我已经找到一种方法来做到这一点,无论图像的大小。您需要创建一个类扩展ImageSpan和覆盖的方法的getSize() getCachedDrawable()(我们不这样做需要改变最后一个,但这种方法从 DynamicDrawableSpan 是私人的,不能在从子类的另一种方式来访问)。在的getSize(...),然后你可以重新定义的方式 DynamicDrawableSpan 设置上升/顶/下降/底部该行并达到你想要做什么。

It might be a bit late but I've found a way to do it, no matter the image size. You need to create a class extending ImageSpan and override the methods getSize() and getCachedDrawable() (we don't need to change the last one, but this method from DynamicDrawableSpan is private and cannot be accessed in another way from the child class). In getSize(...), you can then redefined the way DynamicDrawableSpan set the ascent/top/descent/bottom of the line and achieve what you want to do.

下面是我的类的例子:

public class CenteredImageSpan extends ImageSpan {

    // Extra variables used to redefine the Font Metrics when an ImageSpan is added
    private int initialDescent = 0;
    private int extraSpace = 0;

    public CenteredImageSpan(final Drawable drawable) {
        this(drawable, entry, DynamicDrawableSpan.ALIGN_BOTTOM);
    }

    public CenteredImageSpan(final Drawable drawable, final int verticalAlignment) {
        super(drawable, verticalAlignment);
    }

    @Override
    public Rect getBounds() {
        return getDrawable().getBounds();
    }

    @Override
    public void draw(final Canvas canvas) {
        getDrawable().draw(canvas);
    }


    //
    // Following methods are overriden from DynamicDrawableSpan.
    //

    // Method used to redefined the Font Metrics when an ImageSpan is added
    @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) {
            // Centers the text with the ImageSpan
            if (rect.bottom - (fm.descent - fm.ascent) => 0) {
                // Stores the initial descent and computes the margin available
                initialDescent = fm.descent;
                extraSpace = rect.bottom - (fm.descent - fm.ascent);
            }

            fm.descent = extraSpace / 2 + initialDescent;
            fm.bottom = fm.descent;

            fm.ascent = -rect.bottom + fm.descent;
            fm.top = fm.ascent;
        }

        return rect.right;
    }

    // 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;
    }

    private WeakReference<Drawable> mDrawableRef;
}

让我知道,如果你有这个类的任何麻烦!

Let me know if you have any trouble with that class!

这篇关于调整围绕ImageSpan中心垂直文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆