How to insert drawables in text

倖福魔咒の 提交于 2019-11-27 01:42:48

问题


I want to insert small pictures, like arrow icons for example, into certain positions of contents of a TextView.

The photo below depicts exactly what I want:

Obviously, the most naive solution is to use multiple TextView on either side of the small ImageView objects. But this approach is not scalable.

I am curious to learn if someone has overcome this problem with some simple yet smart trick. (Maybe with help from HTML or an external library)

Any efficient solution is much appreciated.


回答1:


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



回答2:


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




回答3:


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.



来源:https://stackoverflow.com/questions/25521685/how-to-insert-drawables-in-text

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