How to add padding between text and image in SpannableStringBuilder

I want to add a image in text. I used SpannableStringBuilder to achieve that. But I am not able to give padding to the image icon. Please help me to add padding to the image icon.

My code snippet:

String text = "Hello world! ";

        SpannableStringBuilder ssb = new SpannableStringBuilder(text);
        ssb.setSpan(new ImageSpan(this, R.drawable.tick), text.length() - 1, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        tvMainText.setText(ssb, TextView.BufferType.SPANNABLE);

Output:

enter image description here

Here I want to add right and left padding for the image. Please help me on this.

Upvotes: 0

Views: 378

Answers (2)

Vlad Guriev
Vlad Guriev

Reputation: 1924

You can try adding the desired paddings to the drawable itself:

Drawable tick = ContextCompat.getDrawable(context, R.drawable.tick);
LayerDrawable paddedTick = new LayerDrawable(new Drawable[]{tick});
paddedTick.setLayerInset(0, paddingLeft, 0, paddingRight, 0);

ssb.setSpan(new ImageSpan(paddedTick), text.length() - 1, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);

Or create a custom drawable:

public class PaddedDrawable extends Drawable {
    
    private Drawable drawable;
    
    public PaddedDrawable(Drawable drawable, int paddingStartPx, int paddingTopPx, int paddingEndPx, int paddingBottomPx) {
        this.drawable = drawable;
        setBounds(0, 0, drawable.getIntrinsicWidth() + paddingStartPx + paddingEndPx, drawable.getIntrinsicHeight() + paddingTopPx + paddingBottomPx);
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        drawable.draw(canvas);
    }

    @Override
    protected void onBoundsChange(@NonNull Rect bounds) {
        super.onBoundsChange(bounds);
        drawable.setBounds(
            bounds.centerX() - drawable.getIntrinsicWidth(), bounds.centerY() - drawable.getIntrinsicHeight(),
            bounds.centerX() + drawable.getIntrinsicWidth(), bounds.centerY() + drawable.getIntrinsicHeight()
        );
    }

    @Override
    public void setAlpha(int alpha) {}

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {}

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }
}

And then:

Drawable tick = ContextCompat.getDrawable(context, R.drawable.tick);
Drawable paddedTick = new PaddedDrawable(tick, paddingLeft, 0, paddingRight, 0);
ssb.setSpan(new ImageSpan(paddedTick), text.length() - 1, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);

Upvotes: 1

Vishnu S Dharan
Vishnu S Dharan

Reputation: 669

Instead of

String text = "Hello world! ";

Define

text = "Hello world! *symbol* ";

Int startIndex = text.indexOf("*symbol*");

pass the indices of the first and second asterisk (*) as start and end params of setSpan respectively like this

ssb.setSpan(new ImageSpan(this, R.drawable.tick), startIndex, startIndex + 8, Spanned.SPAN_INCLUSIVE_INCLUSIVE);

Upvotes: 0

Related Questions