防止多行TextView不必要地扩展到最大宽度

一个展开成多行的TextView似乎会自动展开以适应其最大宽度。 我怎样才能防止发生?

这是一个布局示例(test.xml)

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white"> <TextView android:background="@color/green" android:layout_alignParentRight="true" android:id="@+id/foo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="right" android:text="This is the message a much shorter message" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@color/black" /> </RelativeLayout> 

显示最大宽度的TextView

如果我在左边添加一个边距,它正确地缩小了TextView的宽度(不重新格式化内容),但是边距的大小必须根据TextView的内容来计算。

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white"> <TextView android:layout_marginLeft="32dp" android:background="@color/green" android:layout_alignParentRight="true" android:id="@+id/foo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="right" android:text="This is the message a much shorter message" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@color/black" /> </RelativeLayout> 

带有边距的TextView显示

Solutions Collecting From Web of "防止多行TextView不必要地扩展到最大宽度"

你可以使用自定义的TextView和重载方法onMeasure()来计算宽度:

 public class WrapWidthTextView extends TextView { ... @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); Layout layout = getLayout(); if (layout != null) { int width = (int)FloatMath.ceil(getMaxLineWidth(layout)) + getCompoundPaddingLeft() + getCompoundPaddingRight(); int height = getMeasuredHeight(); setMeasuredDimension(width, height); } } private float getMaxLineWidth(Layout layout) { float max_width = 0.0f; int lines = layout.getLineCount(); for (int i = 0; i < lines; i++) { if (layout.getLineWidth(i) > max_width) { max_width = layout.getLineWidth(i); } } return max_width; } 

}

使用android:padding="32dp"这有助于你有填充,如果你想从左侧填充使用android:paddingLeft="32dp"

我试过Vitaliy Polchuk的解决scheme,它工作正常。 而且我也想补充一点小小的更正:

 ... @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Layout layout = getLayout(); if (layout != null) { int width = (int) FloatMath.ceil(getMaxLineWidth(layout)) + getCompoundPaddingLeft() + getCompoundPaddingRight(); widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); // get already measured dimensions int width = getMeasuredWidth(); int height = getMeasuredHeight(); setMeasuredDimension(width, height); } ... 

如果你想使用@Vitaliy Polchuk的build议(一个最好的答案),重写或看到他的答案为什么包装内容在多行TextView填充父项? :

 public class WrapWidthTextView extends AppCompatTextView { public WrapWidthTextView(Context context) { super(context); } public WrapWidthTextView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public WrapWidthTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); Layout layout = getLayout(); if (layout != null) { int width = (int) Math.ceil(getMaxLineWidth(layout)) + getCompoundPaddingLeft() + getCompoundPaddingRight(); int height = getMeasuredHeight(); setMeasuredDimension(width, height); } } private float getMaxLineWidth(Layout layout) { float max_width = 0.0f; int lines = layout.getLineCount(); for (int i = 0; i < lines; i++) { if (layout.getLineWidth(i) > max_width) { max_width = layout.getLineWidth(i); } } return max_width; } } 

将此类插入到XML中时重build项目 。 否则它不会find这个类。