Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aligning ImageSpan to the top of the TextView

Currently, I wish to add an image in between texts and align it to the top of the TextView.

Something like this:

enter image description here

The only vertical alignments I can find are baseline (which seems to put it right down the center of the text) and align bottom.

What happens if I use ALIGN_BASELINE is:

enter image description here

Is there a way to align it to the top instead?

My current code:

    txtView.setText(this.addImageAsterisk(
        "The string to have asterisk at the end*"), BufferType.SPANNABLE);

then

private CharSequence addImageAsterisk(String string) {
    Drawable d = context.getResources().getDrawable(R.drawable.img_asterisk); 

    ImageSpan imageSpan = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
    final SpannableString spannableString = new SpannableString(string);
    spannableString.setSpan(imageSpan, string.length()-1, string.length(), 0);
    return spannableString;
}

removing ImageSpan.ALIGN_BASELINE sets it to align to the bottom which is also not my expected result.

--- Thank you user Lalit Poptani, I tried applying your answer---- after applying this, what happens is that the whole textview seems to have extra margin top.

before applying span:

This is the text*

after applying the SuperscriptSpanAdjuster

(some extra space)
This is the text*

My code:

String string = "This is the text*";
Drawable d = this.context.getResources().getDrawable(R.drawable.img_asterisk); 

d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); 

ImageSpan imageSpan = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
SuperscriptSpanAdjuster s = new SuperscriptSpanAdjuster(1.5);
final SpannableString spannableString = new SpannableString(string);
spannableString.setSpan(s, string.length() - 1, string.length(), 0);
spannableString.setSpan(imageSpan, string.length(), string.length() + 1, 0);
textView.setText(spannableString);
like image 319
kiirohana Avatar asked Dec 05 '13 05:12

kiirohana


2 Answers

What you can do is use a custom MetricAffectingSpan for maintaining its ratio like,

public class SuperscriptSpanAdjuster extends MetricAffectingSpan {
    double ratio = 0.5;

    public SuperscriptSpanAdjuster(double ratio) {
        this.ratio = ratio;
    }

    @Override
    public void updateDrawState(TextPaint paint) {
        paint.baselineShift += (int) (paint.ascent() * ratio);
    }

    @Override
    public void updateMeasureState(TextPaint paint) {
        paint.baselineShift += (int) (paint.ascent() * ratio);
    }
}

And the you can use SpannableString to apply asterisk to your String like,

SpannableString mString = new SpannableString("This is what I wanted*");
mString.setSpan(new SuperscriptSpanAdjuster(0.5), mString.length() - 1, 
                     mString.length(), SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
mTextView.append("\n");
mTextView.append(mString);

This is append asterisk to your text as you required. And your output will be as,

enter image description here

like image 117
Lalit Poptani Avatar answered Oct 20 '22 12:10

Lalit Poptani


Just wrap your drawable in inset drawable and set inset bottom to some value like 8dp. Not the best solution, but will work.

Modify your drawable/img_asterisk.xml --

<inset
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetBottom="8dp">

    <!-- Your previous asterisk drawable, probably a 'shape' -->

</inset>
like image 21
Mohit Atray Avatar answered Oct 20 '22 10:10

Mohit Atray