如何排列文字以在图像周围stream动

你能告诉我,如果有一种方式来布置图像周围的文字? 喜欢这个:

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

我已经得到了一个android开发人员对这个问题的回应。 但我不确定他的意思是通过自己的版本的TextView? 感谢任何提示。

在周一,2010年2月8日在下午11:05,罗曼盖伊写道:

嗨,

这仅仅使用提供的小部件和布局是不可能的。 你可以编写自己的TextView版本来做到这一点,不应该很难。

现在有可能,但只能使用版本高于或等于2.2的手机,通过使用API​​ 8中提供的android.text.style.LeadingMarginSpan.LeadingMarginSpan2接口。

这里是文章 ,虽然不是英文,但你可以直接从这里下载示例的源代码。

如果您想让应用程序与旧设备兼容,则可以显示不同的布局而不使用浮动文本。 这里是一个例子:

布局(对于较旧版本的默认设置,将以更新版本的编程方式进行更改)

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

助手类

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

MyLeadingMarginSpan2类(更新为支持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; } } 

使用示例

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

这是应用程序在Android 2.2设备上的外观: Android 2.2的文字在图像周围流动

这是为Android 2.1设备:

Android 2.1的文本位于图像附近

FlowTextHelper的改进(来自vorrtex的回复)。 我添加了在文本和图像之间添加额外填充的可能性,并且改进了线计算以考虑填充。 请享用!

 public class FlowTextHelper { private static boolean mNewClassAvailable; /* class initialization fails when this throws an exception */ static { try { Class.forName("android.text.style.LeadingMarginSpan$LeadingMarginSpan2"); mNewClassAvailable = true; } catch (Exception ex) { mNewClassAvailable = false; } } public static void tryFlowText(String text, View thumbnailView, TextView messageView, Display display, int addPadding){ // 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() + addPadding; messageView.measure(width, height); //to allow getTotalPaddingTop int padding = messageView.getTotalPaddingTop(); float textLineHeight = messageView.getPaint().getTextSize(); // Set the span according to the number of lines and width of the image int lines = (int)Math.round((height - padding) / textLineHeight); SpannableString ss = new SpannableString(text); //For an html text you can use this line: SpannableStringBuilder ss = (SpannableStringBuilder)Html.fromHtml(text); ss.setSpan(new MyLeadingMarginSpan2(lines, width), 0, ss.length(), 0); 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; } } 

这个问题似乎与我的问题是一样的如何填充Android的图像下面的内容的空白空间

我发现使用stream文本库的解决scheme,请find第一个答案,它可能会帮助你到目前为止

Vorrtex和Ronen的答案为我工作,除了一个细节 – 在图像周围环绕文字后,在图像下面和相反的一侧有一个奇怪的“负面”边缘。 我发现,当SpannableString上的跨度设置发生变化时

 ss.setSpan(new MyLeadingMarginSpan2(lines, width), 0, ss.length(), 0); 

 ss.setSpan(new MyLeadingMarginSpan2(lines, width), 0, lines, 0); 

在图像之后停止了跨度。 在所有情况下可能都没有必要,但是我想分享。

“但是我不确定他自己的版本的TextView是什么意思?

他意味着您可以扩展类android.widget.TextView(或Canvas或其他可渲染表面),并实现自己的覆盖版本,允许embedded的图像与文本stream动。

这可能是相当多的工作取决于你如何一般。

现在你可以使用库: https : //github.com/deano2390/FlowTextView 。 喜欢这个:

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

我可以为MyLeadingMarginSpan2类提供更舒适的构造函数

  MyLeadingMarginSpan2(Context cc,int textSize,int height,int width) { int pixelsInLine=(int) (textSize*cc.getResources().getDisplayMetrics().scaledDensity); if (pixelsInLine>0 && height>0) { this.lines=height/pixelsInLine; } else { this.lines=0; } this.margin=width; }