如何在文本中插入drawables

时间:2014-08-27 07:51:39

标签: android user-interface textview imageview

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

下面的照片描绘了我想要的内容:

this is how I want to embed icons in the text

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

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

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

3 个答案:

答案 0 :(得分:14)

您可以创建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);

答案 1 :(得分:7)

有一段时间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步 - 使用图标创建字符串

正如您在addImages(...)类的TextViewWithImages函数中所看到的,字符串中的特殊模式([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>

输出:

enter image description here

如前所述,它会与您的textSize

一起扩展

enter image description here

正如最初所说,这篇文章的大部分摘自18446744073709551615回复here。我认为这应该作为一个库出版,因为在文本中有图像是一个常见的用例。 :其中

答案 2 :(得分:1)

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

有关详细信息,请参阅Android Development: Using Image From Assets In A WebView's HTML