[英]Prevent a multiline TextView from unnecessarily expanding to it's maximum width
扩展为多行的 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 的内容计算。
<?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>
您可以在计算宽度的地方使用带有覆盖方法 onMeasure() 的自定义 TextView:
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;
}
}
如果您想使用@Vitaliy Polchuk 的建议(最佳答案),请重写或查看他的答案, 为什么将内容包装在多行 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 时重建项目。 否则它不会找到这个类。
我已经尝试过Vitaliy Polchuk的解决方案,效果很好。 我还想添加一些小的更正:
...
@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);
}
...
使用android:padding="32dp"
它可以帮助你有填充,如果你想从左边使用android:paddingLeft="32dp"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.