Android中图片周围的文本换行

8

在这里输入图片描述

我正在使用列表视图显示图像和文本,我想要像上面的图片那样显示。 有人可以建议我如何在没有Web视图的情况下围绕图像包裹文本。 我正在使用以下代码:

     Drawable dIcon = getResources().getDrawable(R.drawable.video_icon);
    int leftMargin = dIcon.getIntrinsicWidth() + 10;

    ImageView icon = (ImageView) findViewById(R.id.icon);
    icon.setBackgroundDrawable(dIcon);

    SpannableString ss = new SpannableString(text);
    ss.setSpan(new MyLeadingMarginSpan2(3, leftMargin), 0, ss.length(), 0);

    TextView messageView = (TextView) findViewById(R.id.message_view);
    messageView.setText(ss);

 class MyLeadingMarginSpan2 implements LeadingMarginSpan2 {
    private int margin;
    private int lines;

    MyLeadingMarginSpan2(int lines, int margin) {
        this.margin = margin;
        this.lines = lines;
    }

    @Override
    public int getLeadingMargin(boolean first) {
        if (first) {
            return margin;
        } else {
            return 0;
        }
    }

    @Override
    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, 
            int top, int baseline, int bottom, CharSequence text, 
            int start, int end, boolean first, Layout layout) {}

    @Override
    public int getLeadingMarginLineCount() {
        return lines;
    }
};

使用此代码,我得到了下面的图像,请建议如何正确地将文本环绕在图像周围,而不会有更多的空白空间。

wrapping text around image


2
答案在这里:https://dev59.com/uHE95IYBdhLWcg3wlu0g - IAmGroot
我一直在研究你所使用的类似代码版本。据我所知,文本中的换行符会导致没有应用边距的行比它们应该的长度要短。去掉换行符,它就可以整齐地流动了。不幸的是,我还没有想出如何同时拥有标题和流动文本的方法。 - Keab42
嗨,我该如何在其中应用HTML标签?请帮帮我。 - Harsha
你好 Raju。你知道怎么逐步编写“将文本环绕在图像周围”的代码吗?我还试图将此代码设置为屏幕右侧放置的图像。谢谢。 - Ramona
1个回答

2

虽然这篇文章比较旧,但是由于没有被接受的答案,而我刚好在我的应用程序中找到了同样问题的解决方案,所以我将提供一种解决方案。

我发现没有任何换行符的文本效果很好。如果有一个换行符把文本分成两部分,使得换行符前的部分在图像右侧结束,换行符后的部分则在下一行开始,这也可以正常工作。

所以我的做法是,我将包裹TextView的LayoutParams的左边距设置为所需的缩进,并将文本设置到TextView中。然后我添加OnGlobalLayoutListener,在onGlobalLayout回调中,计算图像右侧最后一行的最后一个字符的位置。

//lines - number of lines to be affected by the leadingMargin    
int charCount = textView.getLayout().getLineEnd(Math.min(lines - 1, textView.getLayout().getLineCount() - 1));

如果文本行数不超过左边距规定的行数(或者最后一个字符已经是换行符),我会在整个文本长度上设置LeadingMarginSpan2。

// s - original Spannable containing the whole text
if (charCount >= s.length() || charCount <= 0 || s.charAt(charCount - 1) == '\n') {
                    s.setSpan(new MyLeadingMarginSpan(lines, w), 0, charCount, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    textView.setText(s);
}

如果文本较长,我会将其分为两部分(第一部分以charCount位置结尾),在它们之间插入换行符,合并它们,并仅在第一部分上设置LeadingMarginSpan2。
else {
    Spannable s1 = new SpannableStringBuilder(s, 0, charCount);
    s1.setSpan(new MyLeadingMarginSpan(lines, w), 0, charCount, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    Spannable s2 = new SpannableStringBuilder(System.getProperty("line.separator"));
    Spannable s3 = new SpannableStringBuilder(s, charCount, s.length());
    textView.setText(TextUtils.concat(s1, s2, s3));
}

在最后,不要忘记移除TextView的LayoutParams的左边距。

大家好。我正在尝试实现将图像放置在屏幕右侧的代码。如何实现呢?还有第二个问题 - 在哪里可以找到关于编写类似于你的代码的逐步说明?非常感谢。 - Ramona
右侧的图像很容易处理: - 将TextView的右边距设置为图像所需的空间。然后,在OnGlobalLayout之后,使用图像的高度计算出与图像相邻适合的行数(使用ImageView的高度与TextView的textSize、lineSpacingMultiplier、padding等)。 然后,在这些行的每个末尾添加换行符(以防最后一个字符不是换行符)。 - david.s
哎呀,不小心按了回车键,现在我不能编辑它了。右侧的图像很容易实现: 1.设置TextView的右边距以适应您需要的图像空间。 2.在OnGlobalLayout后,使用图像的高度,计算有多少行适合放置在图像旁边(使用ImageView的高度与TextView的textSize、lineSpacingMultiplier、padding等)。 3.在这些前x行的末尾添加换行符(以防最后一个字符不是换行符)。 4.移除右边距。 现在,由于在末尾添加了换行符,前x行会变短,而其余的行将扩展到整个宽度。 - david.s
关于逐步解释 - 我不知道有没有。我不得不从这里和那里的碎片以及自己的尝试中弄清楚这个问题。然而,我的代码从那时起变得相当庞大,有太多与一般用途无关的代码。 但是根据回答和评论中发布的信息,您应该能够将其组合在一起。 - david.s
你好,感谢您的回复。所以我应该将您的建议应用到我的代码中,就像这个 https://stackoverflow.com/questions/45615230/text-wrap-around-image-in-fragments?noredirect=1#comment78190916_45615230 ?我是一个初学者,有点迷失,抱歉。 - Ramona

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接