Java – Wrappable TextView with SpannableStringBuilder and ImageSpan hides the last image of each line

Wrappable TextView with SpannableStringBuilder and ImageSpan hides the last image of each line… here is a solution to the problem.

Wrappable TextView with SpannableStringBuilder and ImageSpan hides the last image of each line

I’m dynamically populating a multiline TextView with elements. The lines of the input element are wrapperable. Each element consists of two parts: text and images. The length of the picture is 2 characters. Elements are separated by spaces. To add elements, I used SpannableStringBuilder. Except for one thing, everything is fine. When you add a new element to the next line (TextView line break), the image of the previous element (that is, the last element of the previous line) disappears, regardless of how much space is available on that line. If I delete the newly added element in a new row, the image appears again. Therefore, the image portion of the last element of each line is not displayed. 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 TextWatcher has a solution. At the same time, I don’t see any flow in the code and don’t understand why the last image of each line is hidden. Any suggestions would be appreciated. Thank you.

Solution

I found a solution. The problem is how lines of text are calculated. If a line ends with a space character, the space is ignored during calculation. So, all you have to do is to use any letter as a placeholder for your image. Like this:

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

PS: I don’t know why you want to use a 2-character String for each picture, but I have to say you can only use one Char. This is a more efficient code:

int start = ssb.length();
ssb.append('i');
ssb.setSpan(new ImageSpan(image), start, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Related Problems and Solutions