Open mianaliasjad opened 4 years ago
This is the desired behavior and it is achieved when I don't use OutlineSpan.
This is what happens when I use OutlineSpan with StaticLayout. You can see grey background shows that width is set less but OutlineSpan is still drawing text on canvas by taking complete width.
Don't get confused there was \n in this text that's why are you is in second line. If \n was not there it would still be in one big line going out of grey area.
Hello @mianaliasjad, can you provide your layout file (xml) and code that outline your text?
@santaevpavel there no xml file. As i told earlier i am drawing text myself in onDraw(Canvas c)
of view using StaticLayout
@mianaliasjad ok, can you provide body of your onDraw(Canvas)
method? I need it to reproduce the issue
@Override
protected void onDraw(Canvas canvas) {
String txt = "This is the text";
final Spannable spannableString = new SpannableString(txt);
final OutlineSpan outLineSpan = new OutlineSpan(textBorderPaint, textPaint.getFontMetricsInt());
spannableString.setSpan(outLineSpan, 0, txt.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
final float w2 = StaticLayout.getDesiredWidth(txt, textPaint) * 0.5f; //here i am taking half of actual required width for this text
StaticLayout staticLayout = new StaticLayout(spannableString, textPaint, (int) w2, Layout.Alignment.ALIGN_NORMAL, 1, lineSpacing, false);
staticLayout.draw(canvas);
}
In this code the class OutlineSpan is as following its functionality is same as yours but I have made a few changes according to my need:
public class OutlineSpan extends ReplacementSpan{
private TextPaint borderPaint;
private Paint.FontMetricsInt fontMetricsInt;
public OutlineSpan(TextPaint borderPaint, Paint.FontMetricsInt fontMetricsInt){
this.borderPaint = borderPaint;
this.fontMetricsInt=fontMetricsInt;
}
@Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {
if (fm != null) {
fm.top=fontMetricsInt.top;
fm.leading=fontMetricsInt.leading;
fm.bottom=fontMetricsInt.bottom;
fm.descent=fontMetricsInt.descent;
fm.ascent=fontMetricsInt.ascent;
}
return (int)paint.measureText(text.toString().substring(start,end));
}
@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
canvas.drawText(text, start, end, x, y, borderPaint); //first draw text with border paint then draw simple text
canvas.drawText(text, start, end, x, y, paint);
}
}
Now just play with the width that we pass to StaticLayout. No matter what you set when OutlineSpan is used it draws text by taking the actual width that it requires.
Let me know if you still have any confusion in this code. Thanks
@mianaliasjad Hi, sorry for delay. I was in vacation. Is this issue actual?
@santaevpavel yes it is. Have you looked at it? I am using it because I want to draw text with the border. But if I don't use it then I have to draw two different static layouts in order to draw a border also.
I am using this OutlineSpan with StaticLayout.
It works fine when I pass the width to the static layout by measuring like that
StaticLayout.getDesiredWidth(txt, textPaint);
But When i set less width than the actual width that will wrap the text then It is the property of static layout that it automatically increases the number of lines of the text and keeps the width the one that we provide.
But when I use OutlineSpan and decrease the width it doesn't increase the number of lines instead it just draw the text with its complete width that will wrap the text.
In short, using OutlineSpan and StaticLayout with less width does not affect anything it just draws the text with actual width.
I hope you will understand my problem if you have worked with StaticLayout. Otherwise please ask me questions. Thanks