Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to layout text to flow around an image

Can you please tell me if there is a way to layout text around an image? Like this:

------  text text text |    |  text text text -----   text text text text text text text text text text text 

I have gotten a response from an android developer about this question. But I am not sure what he means by doing my own version of TextView? Thank for any tips.

On Mon, Feb 8, 2010 at 11:05 PM, Romain Guy wrote:

Hi,

This is not possible using only the supplied widgets and layouts. You could write your own version of TextView to do this, it shouldn't be hard.

like image 594
silverburgh Avatar asked Feb 12 '10 00:02

silverburgh


People also ask

How do I make text flow around an image in HTML?

Use the markup code <BR CLEAR=”left” /> to flow text around images on opposite sides of your Web pages.

What option controls how text flows around an image?

The Behind Text option causes the text to flow over the image.


2 Answers

Now it is possible, but only for phones with version higher or equal 2.2 by using the android.text.style.LeadingMarginSpan.LeadingMarginSpan2 interface which is available in API 8.

Here is the article, not in English though, but you can download the source code of the example directly from here.

If you want to make your application compatible with older devices, you can display a different layout without a floating text. Here is an example:

Layout (default for older versions, will be changed programmatically for newer versions)

<RelativeLayout     xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="fill_parent"     android:layout_height="wrap_content">     <ImageView              android:id="@+id/thumbnail_view"             android:src="@drawable/icon"             android:layout_width="wrap_content"             android:layout_height="wrap_content" />      <TextView android:id="@+id/message_view"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:layout_toRightOf="@id/thumbnail_view"             android:textSize="18sp"             android:text="@string/text" /> </RelativeLayout> 

The helper class

class FlowTextHelper {      private static boolean mNewClassAvailable;      static {         if (Integer.parseInt(Build.VERSION.SDK) >= 8) { // Froyo 2.2, API level 8            mNewClassAvailable = true;         }     }      public static void tryFlowText(String text, View thumbnailView, TextView messageView, Display display){         // There is nothing I can do for older versions, so just return         if(!mNewClassAvailable) return;          // Get height and width of the image and height of the text line         thumbnailView.measure(display.getWidth(), display.getHeight());         int height = thumbnailView.getMeasuredHeight();         int width = thumbnailView.getMeasuredWidth();         float textLineHeight = messageView.getPaint().getTextSize();          // Set the span according to the number of lines and width of the image         int lines = (int)FloatMath.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);         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;     } } 

The MyLeadingMarginSpan2 class (updated to support API 21)

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;     } } 

Example of the usage

ImageView thumbnailView = (ImageView) findViewById(R.id.thumbnail_view); TextView messageView = (TextView) findViewById(R.id.message_view); String text = getString(R.string.text);  Display display = getWindowManager().getDefaultDisplay(); FlowTextHelper.tryFlowText(text, thumbnailView, messageView, display); 

This is how the application looks on the Android 2.2 device: Android 2.2 the text flows around the image

And this is for the Android 2.1 device:

Android 2.1 the text is situated near the image

like image 98
vortexwolf Avatar answered Sep 27 '22 22:09

vortexwolf


Nowadays you can use library: https://github.com/deano2390/FlowTextView . Like this:

<uk.co.deanwild.flowtextview.FlowTextView     android:id="@+id/ftv"     android:layout_width="fill_parent"     android:layout_height="wrap_content" >          <ImageView             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:layout_alignParentLeft="true"             android:layout_alignParentTop="true"             android:padding="10dip"             android:src="@drawable/android"/> </uk.co.deanwild.flowtextview.FlowTextView> 
like image 37
Nikita Shaposhnik Avatar answered Sep 27 '22 23:09

Nikita Shaposhnik