I'm using LeadingSpanMargin2
as suggested to style my TextView
so that it would flow around an Image
, the problem is the text I set is dynamic and can be rtl or ltr.
I tried anything I could think of to fix the leadingMargin
so that it would be either right or left in both cases, to no avail.
Also the I've tried FlowTextView
widget posted in github and it doesn't work well in rtl cases, so please do not suggest that.
Many thanks.
Here's the code I use, which was suggested in another answer:
public void setFlowText(CharSequence text, int width , int height, TextView messageView)
{
float textLineHeight = messageView.getPaint().getTextSize();
// Set the span according to the number of lines and width of the image
int lines = (int)Math.ceil(height / textLineHeight);
//For an html text you can use this line: SpannableStringBuilder ss = (SpannableStringBuilder)Html.fromHtml(text);
SpannableString ss = new SpannableString(text);
ss.setSpan(new MyLeadingMarginSpan2(lines, width), 0, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//ss.setSpan(new AlignmentSpan.Standard(Alignment.ALIGN_OPPOSITE), 0, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
messageView.setText(ss);
// Align the text with the image by removing the rule that the text is to the right of the image
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)messageView.getLayoutParams();
int[]rules = params.getRules();
rules[RelativeLayout.RIGHT_OF] = 0;
}
public class MyLeadingMarginSpan2 implements LeadingMarginSpan2 {
private int margin;
private int lines;
private boolean wasDrawCalled = false;
private int drawLineCount = 0;
public MyLeadingMarginSpan2(int lines, int margin) {
this.margin = margin;
this.lines = lines;
}
@Override
public int getLeadingMargin(boolean first) {
boolean isFirstMargin = first;
// a different algorithm for api 21+
if (Build.VERSION.SDK_INT >= 21) {
this.drawLineCount = this.wasDrawCalled ? this.drawLineCount + 1 : 0;
this.wasDrawCalled = false;
isFirstMargin = this.drawLineCount <= this.lines;
}
return isFirstMargin ? this.margin : 0;
}
@Override
public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {
this.wasDrawCalled = true;
}
@Override
public int getLeadingMarginLineCount() {
return this.lines;
}
}
For the some unknown reason you can get left margin by passing:
ss.setSpan(new MyLeadingMarginSpan2(lines, width), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
and to get right margin you need to pass:
ss.setSpan(new MyLeadingMarginSpan2(lines, width), 1, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
I don't know what is going on there, but this works!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With