How to insert drawables in text

扶醉桌前 提交于 2019-11-28 06:58:44

You can create SpannableString and add any object to your string

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);
reVerse

There was a similiar question a while back and someone came up with an awesome solution. I've just tweaked this one a little bit so that the image-size is always as tall as the line. So basically your icons will scale with the textSize.

Step 1 - Create a new View

Create a new Java class which extends TextView

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

Step 2 - Usage in layout

Now in your layout-xml just use the TextViewWithImages class

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

Step 3 - Creating strings with icons

As you can see in the addImages(...) function of the TextViewWithImages class, a special pattern ([img src=my_icon/]) within the string is used in order to add the images. So here's a example:

<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>

The output:

And as previously said it will scale with your textSize:

As initially said most of this post is taken from 18446744073709551615 answer here. I think this should be published as a library since it's a common use-case to have images in the text. :<

Lars Blumberg

An option is to use a WebView instead of a TextView. This also allows you to display images from your asset folder.

See Android Development: Using Image From Assets In A WebView's HTML for more details.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!