8

enter image description here

I am using list view to show image and text i want to show like above image, can anyone suggest me how to wrap text around image with out webview. I am using following code:

     Drawable dIcon = getResources().getDrawable(R.drawable.video_icon);
    int leftMargin = dIcon.getIntrinsicWidth() + 10;

    ImageView icon = (ImageView) findViewById(R.id.icon);
    icon.setBackgroundDrawable(dIcon);

    SpannableString ss = new SpannableString(text);
    ss.setSpan(new MyLeadingMarginSpan2(3, leftMargin), 0, ss.length(), 0);

    TextView messageView = (TextView) findViewById(R.id.message_view);
    messageView.setText(ss);

class

 class MyLeadingMarginSpan2 implements LeadingMarginSpan2 {
    private int margin;
    private int lines;

    MyLeadingMarginSpan2(int lines, int margin) {
        this.margin = margin;
        this.lines = lines;
    }

    @Override
    public int getLeadingMargin(boolean first) {
        if (first) {
            return margin;
        } else {
            return 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) {}

    @Override
    public int getLeadingMarginLineCount() {
        return lines;
    }
};

by using this code iam getting below image pls suggest to how to get first means correct wrapping text around image without more empty spaces

wrap text around image

raju
  • 785
  • 3
  • 14
  • 28
  • 2
    Answer is here: http://stackoverflow.com/questions/2248759/how-to-layout-text-to-flow-around-an-image – IAmGroot Jul 02 '13 at 08:15
  • I've been looking at a similar version of the code you're using. As far as I can tell line breaks in the text that's being wrapped causes lines that don't have the margin applied to be shorter than they should be. Remove the line breaks and it'll flow neatly. Unfortunately I haven't yet worked out how to have a title and still flow the text. – Keab42 Aug 21 '13 at 16:29
  • hi how can i apply html tags also in that plse help me – Harsha Nov 27 '14 at 11:47
  • hello raju. do you know by any chance how to write this 'wrap text around image' code step by step? im also trying to set this code for image placed on the right side of the screen. thank you. – Ramona Aug 09 '17 at 15:20

1 Answers1

2

Older post, but since there is no accepted answer and I have just found solution for same problem in my app, I will post a solution.

I have discovered that text without any line break works well. Text with a line break that splits the text into 2 parts in a way that the part before line break ends to the right of the image, and the part after line break starts already on next line bellow the image, this also works well.

So what I do is I set left margin of the wrapping TextView's LayoutParams to the desired indent, and I set the text into TextView. Then I add OnGlobalLayoutListener, and inside onGlobalLayout callback, I count the position of the last character on the last line to the right of the image

//lines - number of lines to be affected by the leadingMargin    
int charCount = textView.getLayout().getLineEnd(Math.min(lines - 1, textView.getLayout().getLineCount() - 1));

If the text does not have more lines than the number of lines that should have the left margin (or if the last character is already line break), I just set the LeadingMarginSpan2 on the whole length of the text.

// s - original Spannable containing the whole text
if (charCount >= s.length() || charCount <= 0 || s.charAt(charCount - 1) == '\n') {
                    s.setSpan(new MyLeadingMarginSpan(lines, w), 0, charCount, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    textView.setText(s);
}

If the text is longer, I split it into 2 parts (first one ending at the charCount position), insert line break between them, merge them and set the LeadingMarginSpan2 only on the first part.

else {
    Spannable s1 = new SpannableStringBuilder(s, 0, charCount);
    s1.setSpan(new MyLeadingMarginSpan(lines, w), 0, charCount, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    Spannable s2 = new SpannableStringBuilder(System.getProperty("line.separator"));
    Spannable s3 = new SpannableStringBuilder(s, charCount, s.length());
    textView.setText(TextUtils.concat(s1, s2, s3));
}

At the end, do not forget to remove the left margin of the TextView's LayoutParams.

david.s
  • 16,880
  • 3
  • 13
  • 11
  • Hi there. I'm trying to implement this code for image placed on the right side of the screen. How to do so? And second question - where to find step by step explanation on how to write such code as yours? Many thanks. – Ramona Aug 09 '17 at 15:18
  • Image on right is easy: - set the TextView's right margin to be the space you need for your image. Then, after OnGlobalLayout, using the height of the image, count how many lines fit next to the image (using ImageView's height vs TextView's textSize, lineSpacingMultiplier, padding etc.). Then, at the end of each of these lines, add line break (in case the last char is not line break already). – david.s Aug 14 '17 at 07:53
  • Gee, pressed ENTER by mistake, now I cannot edit it. Image on right is easy: 1. set the TextView's right margin to be the space you need for your image. 2. After OnGlobalLayout, using the height of the image, count how many lines fit next to the image (using ImageView's height vs TextView's textSize, lineSpacingMultiplier, padding etc.). 3. At the end of each of these first x lines, add line break (in case the last char is not line break already). 4. Remove the right margin. Now the first x lines will be shorter due to line break at the end, the rest will expand to the whole width – david.s Aug 14 '17 at 08:00
  • As for step-by-step explanation - there is none I know of. I had to figure this from bits here and there and from my own attempts. My code however got quite large since then, with too much code not relevant for general use. But with the information posted in the answer + comment, you should be able to put it together. – david.s Aug 14 '17 at 08:06
  • Hello ,thank you for your reply. So I should just apply your advice to my code which is like this https://stackoverflow.com/questions/45615230/text-wrap-around-image-in-fragments?noredirect=1#comment78190916_45615230 ? I'm a beginner and got a bit lost, sorry. – Ramona Aug 15 '17 at 07:52