How to insert drawables in text

后端 未结 3 1365
没有蜡笔的小新
没有蜡笔的小新 2020-12-05 11:02

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

相关标签:
3条回答
  • 2020-12-05 11:40

    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);
    
    0 讨论(0)
  • 2020-12-05 11:44

    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:

    enter image description here

    And as previously said it will scale with your textSize:

    enter image description here

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

    0 讨论(0)
  • 2020-12-05 11:47

    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.

    0 讨论(0)
提交回复
热议问题