簡體   English   中英

防止多行 TextView 不必要地擴展到其最大寬度

[英]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 的寬度(不重新格式化內容),但邊距的大小必須根據 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 顯示有邊距

您可以在計算寬度的地方使用帶有覆蓋方法 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM