Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrappable TextView with SpannableStringBuilder and ImageSpan hides the last image on every line

I'm dynamically populating a multiline TextView with elements. The line of entered elements is wrappable. Each element consists of two parts: a text followed by an image. The length of the image is 2 characters. Elements are separated by a space. For adding elements I'm using SpannableStringBuilder. Everything works fine except for one thing. While adding a new element that goes to the next line (TextView wraps the line), the image of the previous element, that is the last one on the line above, disappears regardless of how much space is still available on that line. And if I remove the newly added element on the new line, that image reappears again. So the image part of every element that is last on every line doesn't show up. I'm using Android 4.0.3.

Here is my code:

TextView textView = (TextView) findViewById(R.id.textview);
textView.setMovementMethod(new ScrollingMovementMethod());

SpannableStringBuilder ssb = new SpannableStringBuilder();

//then for each new element I do the following
ssb.append(" "); //space separating elements (skip for the first element)
ssb.append("text");
Bitmap image = BitmapFactory.decodeResource( getResources(), imageId );
ssb.append("  "); //prepare 2-character space for the image
ssb.setSpan( new ImageSpan(image), ssb.length() - 2, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ); //put the image to the prepared space
textView.setText( ssb, BufferType.SPANNABLE );

I know that there is a solution with TextWatcher. At the same time, I don't see any flows in my code and can't understand why the last image on every line gets hidden. Any suggestions will be highly appreciated. Thanks.

like image 774
user3334038 Avatar asked Oct 18 '25 05:10

user3334038


1 Answers

I've found the solution. The problem is in the way of calculating of text lines. If a line ends up with a space character, then this space is being omitted during calculations. So, all you have to do is to use any letter as a placeholder for your images. Like this:

ssb.append(" i"); //prepare 2-characters for the image

PS: I don't know why are you using 2 character String for every image, but I have to say that you can use only one Char. Here is a bit more efficient code:

int start = ssb.length();
ssb.append('i');
ssb.setSpan(new ImageSpan(image), start, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
like image 121
Oleg Cherr Avatar answered Oct 19 '25 21:10

Oleg Cherr