【问题标题】:How to insert drawables in text如何在文本中插入可绘制对象
【发布时间】:2014-10-20 17:10:01
【问题描述】:

我想在TextView 内容的某些位置插入小图片,例如箭头图标。

下面的照片正是我想要的:

显然,最天真的解决方案是在小的ImageView 对象的两侧使用多个TextView。但这种方法不可扩展。

我很想知道是否有人用一些简单而聪明的技巧克服了这个问题。 (也许在 HTML 或外部库的帮助下)

非常感谢任何有效的解决方案。

【问题讨论】:

  • @Egor:这很好,但提供的文本只放在图像之后,所以在上图的情况下,我必须利用并对齐 5 个 IconTextView 对象,外加 1 个 TextView。
  • 这个错误发生在什么时候?不敢相信它会立即出现,为了正确地帮助你,你应该添加你当前的布局。
  • 我已经包含了布局,只有当我为我的 TextViewWithImage 对象设置超过两行文本时才会出现问题。

标签: android user-interface textview imageview


【解决方案1】:

您可以创建 SpannableString 并将任何对象添加到您的字符串中

TextView textView = (TextView) findViewById(R.id.textView);

ImageSpan imageSpan = new ImageSpan(this, R.drawable.ic_launcher);
SpannableString spannableString = new SpannableString(textView.getText());

int start = 3;
int end = 4;
int flag = 0;
spannableString.setSpan(imageSpan, start, end, flag);

textView.setText(spannableString);

【讨论】:

  • 您能详细说明一下吗?我有 5 张图片要放入文本中,而不仅仅是一张。您的解决方案能否按比例扩大以满足我提出的需求?
  • 为您要插入的每个图像添加一个新的 ImageSpan 到 spannableString。
  • 如何从网络加载图像跨度?谢谢
【解决方案2】:

不久前有一个similiar question,有人想出了一个很棒的解决方案。我刚刚稍微调整了一下,这样图像大小总是和线条一样高。所以基本上你的图标会随 textSize 缩放

第 1 步 - 创建新视图

创建一个扩展 TextView 的新 Java 类

public class TextViewWithImages extends TextView {

    public TextViewWithImages(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

    }
    public TextViewWithImages(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public TextViewWithImages(Context context) {
        super(context);
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        Spannable s = getTextWithImages(getContext(), text, this.getLineHeight());
        super.setText(s, BufferType.SPANNABLE);
    }

    private static final Spannable.Factory spannableFactory = Spannable.Factory.getInstance();

    private static boolean addImages(Context context, Spannable spannable, float height) {
        Pattern refImg = Pattern.compile("\\Q[img src=\\E([a-zA-Z0-9_]+?)\\Q/]\\E");
        boolean hasChanges = false;

        Matcher matcher = refImg.matcher(spannable);
        while (matcher.find()) {
            boolean set = true;
            for (ImageSpan span : spannable.getSpans(matcher.start(), matcher.end(), ImageSpan.class)) {
                if (spannable.getSpanStart(span) >= matcher.start()
                        && spannable.getSpanEnd(span) <= matcher.end()
                        ) {
                    spannable.removeSpan(span);
                } else {
                    set = false;
                    break;
                }
            }
            String resName = spannable.subSequence(matcher.start(1), matcher.end(1)).toString().trim();
            int id = context.getResources().getIdentifier(resName, "drawable", context.getPackageName());
            Drawable mDrawable = context.getResources().getDrawable(id);
            mDrawable.setBounds(0, 0, (int)height, (int)height);
            if (set) {
                hasChanges = true;
                spannable.setSpan(  new ImageSpan(mDrawable),
                        matcher.start(),
                        matcher.end(),
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                );
            }
        }

        return hasChanges;
    }
    private static Spannable getTextWithImages(Context context, CharSequence text, float height) {
        Spannable spannable = spannableFactory.newSpannable(text);
        addImages(context, spannable, height);
        return spannable;
    }
}

第 2 步 - 布局中的用法

现在在你的 layout-xml 中使用 TextViewWithImages 类

<com.stacko.examples.TextViewWithImages
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="14sp"
    android:text="@string/my_string_with_icons" />

第 3 步 - 创建带有图标的字符串

正如您在TextViewWithImages 类的addImages(...) 函数中所见,字符串中的特殊模式([img src=my_icon/])用于添加图像。 所以这里有一个例子:

<string name="my_string_with_icons">The [img src=ic_action_trash/] is used to delete an item while the [img src=ic_action_edit/] is to edit one.</string>

输出:

如前所述,它将随您的 textSize 扩展:

正如最初所说,这篇文章的大部分内容来自18446744073709551615 答案here。我认为这应该作为一个库发布,因为在文本中包含图像是一个常见的用例。 :

【讨论】:

  • 哇,好漂亮,一定要试试!我在图书馆项目上完全听到了你的声音。
  • 关于崩溃的任何想法?
  • 不幸的是,我无法重现该错误。我刚刚为我的TextViewWithImages 设置了 20 行,并且没有发生崩溃。您的设备在哪个 Android 版本上运行?
  • 4.2.2,我需要插入最多 5 个可绘制对象。
  • @j2emanue 那么drawable的大小设置为线本身的高度(在添加图像之前)。它可能是在 Drawable#setBounds 方法中减小尺寸的一个选项。
【解决方案3】:

一个选项是使用WebView 而不是TextView。这还允许您显示资产文件夹中的图像。

更多详情请见Android Development: Using Image From Assets In A WebView's HTML

【讨论】:

  • 这是个好主意,尽管我宁愿使用可绘制文件夹而不是资产,因为我需要有效地为不同的区域设置和屏幕使用不同的图像。无论如何,我很欣赏你的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
  • 1970-01-01
  • 2021-06-15
  • 1970-01-01
  • 2013-04-01
相关资源
最近更新 更多