Android TextView截断优先级或压缩阻力

Android TextView截断优先级或压缩阻力,android,xml,textview,truncation,Android,Xml,Textview,Truncation,我在屏幕上水平布置了3个视图(固定大小的图像和2个单行文本视图:leftTextView和rightextview),我试图让rightextview与leftTextView相紧贴,但如果两个标签的宽度都超过屏幕大小,截断左文本视图 所需功能的示例: |img|leftText|rightText| ||(end of screen) |img|leftTextMedium|rightText| || |img|leftTextTooLongSo

我在屏幕上水平布置了3个视图(固定大小的图像和2个单行文本视图:
leftTextView
rightextview
),我试图让
rightextview
leftTextView
相紧贴,但如果两个标签的宽度都超过屏幕大小,截断
左文本视图

所需功能的示例:

|img|leftText|rightText|                ||(end of screen)
|img|leftTextMedium|rightText|          ||
|img|leftTextTooLongSoTrunc...|rightText||
实际发生的情况:

|img|leftText|rightText|                ||(end of screen)
|img|leftTextPrettyLongButNotHuge|rightT||
|img|leftTextWhichIsIncrediblyLongBlahBl||
目前,如果两个文本视图的大小都超过了视图的宽度,则
rightTextView
最终会被压扁以腾出空间,即使我在
leftTextView
上设置了
android:ellipsize=“end”

有没有办法使
leftTextView
具有“截断优先级”,即如果它会导致其他视图不适合,则应该截断?或者在另一侧,我是否可以将
rightextview
设置为具有“压缩阻力”,以防止其被挤压,从而为
leftTextView
腾出空间?以下是我的XML示例:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/fixedWidthImage"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:id="@+id/leftTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toEndOf="@+id/fixedWidthImage"
        android:layout_toRightOf="@id/fixedWidthImage"
        android:maxLines="1"
        android:textSize="18sp"
        android:ellipsize="end" />

    <TextView
        android:id="@+id/rightTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toEndOf="@+id/leftTextView"
        android:layout_toRightOf="@+id/leftTextView"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:maxLines="1"
        android:textSize="12sp" />

</RelativeLayout>
  • 即使我设置
    android:minWidth=“25dp”
    只是为了确保至少部分
    rightTextView
    可见(我不想这样做,因为此文本长度是可变的),它仍然会压缩宽度,为
    leftTextView
    腾出空间

  • Per的回答是,我尝试使用
    线性布局
    ,并在
    左文本视图
    上设置权重。结果在视觉上与我在#2中尝试的完全相同
  • 我是这样做的:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    
        <ImageView
            android:id="@+id/fixedWidthImage"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@drawable/ic_launcher_pro" />
    
        <TextView
            android:id="@+id/leftTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_gravity="center_vertical|left"
            android:ellipsize="marquee"
            android:lines="1"
            android:text="This is a very long text, and now even longer" />
    
        <TextView
            android:id="@+id/rightTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical|left"
            android:lines="1"
            android:text="This is also quite long" />
    
    </LinearLayout>
    
    
    
    android:layout_weight=“1”在这里起“作用”。不过,关于这一点的文档并不十分清楚:

    例如,如果有三个文本字段,其中两个声明 权重为1,而另一个没有权重,第三个文本字段 没有重量就不会增长,只会占据 它的内容

    ()


    它没有详细说明没有空间填充但没有足够的空间容纳所有视图的情况。对上述文档的一种解释是,没有权重的字段(本例中为rightTextView)将占据其内容所需的区域,而有权重的字段(本例中为leftTextView)将“增长”(如负增长)这正是发生的情况。

    我认为您需要定制布局。这对我制作的示例很有效,它满足了上面发布的所有要求,但您需要在代码中添加更多的数学元素,以说明布局的边距和填充

    这里发生的事情的基本思想是我将LinearLayout子类化,在onMeasure过程中,我检查以确保right view可以选择占用尽可能多的空间。请注意,我必须重新测量正确的视图,而不仅仅是获得测量的宽度,因为线性布局不会给它足够的空间。一旦右视图占据了多少空间,请检查中间视图(称为leftView…对不起)是否占据了比您想要的更多的空间。如果有,就给它剩下的空间

    根据您的要求,它是在一个回收视图。。。我知道您说过您想要一个纯xml解决方案,但如果您以xml 1的形式在代码中处理它,您将获得更好的性能。可能是不可能的。将需要更多的计算,而不仅仅是自己直接做

    public class CustomLinearLayout extends LinearLayout {
    
    private View child0;
    private TextView leftView, rightView;
    public CustomLinearLayout(Context context) {
        super(context);
    }
    
    public CustomLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (rightView == null) {
            child0 = getChildAt(0);
            leftView = (TextView)getChildAt(1);
            rightView = (TextView) getChildAt(2);
        }
    
        int spec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST);
        rightView.measure(spec, spec);
    
        int remaining = getMeasuredWidth() - child0.getMeasuredWidth() - rightView.getMeasuredWidth();
        if (leftView.getMeasuredWidth() > remaining) {
            int specW = MeasureSpec.makeMeasureSpec(remaining, MeasureSpec.AT_MOST);
            int specH = MeasureSpec.makeMeasureSpec(leftView.getMeasuredHeight(), MeasureSpec.EXACTLY);
            leftView.measure(specW, specH);
        }
    }
    
    XML布局

    <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.joshua.myapplication.MainActivity">
    
    <com.example.joshua.myapplication.CustomLinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <ImageView
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:background="#FF0000"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:maxLines="1"
            android:textSize="18sp"
            android:text="My Left View With Really Really Long Text That should fill the screen"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:maxLines="1"
            android:textSize="18sp"
            android:text="My Right View"
            />
    </com.example.joshua.myapplication.CustomLinearLayout>
    
    <com.example.joshua.myapplication.CustomLinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="20dp">
        <ImageView
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:background="#FF0000"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:maxLines="1"
            android:textSize="18sp"
            android:text="My Left View with short text"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:maxLines="1"
            android:textSize="18sp"
            android:text="My Right View"
            />
    </com.example.joshua.myapplication.CustomLinearLayout>
    </LinearLayout>
    
    
    

    只需在左侧文本视图中使用android:maxWidth属性即可。因此,您的leftview将永远不会超过该限制。而且,你的正确视角总是有空间的

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
    
        <ImageView
            android:id="@+id/fixedWidthImage"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:src="@drawable/ic_launcher" />
    
        <TextView
            android:id="@+id/leftTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toEndOf="@+id/fixedWidthImage"
            android:layout_toRightOf="@+id/fixedWidthImage"
            android:ellipsize="end"
            android:lines="1"
            android:maxWidth="250dp"
            android:text="This is a Long left Text which never ends and You'll be tired after reading this long stuff.. blah blah... " />
    
        <TextView
            android:id="@+id/rightTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toEndOf="@+id/leftTextView"
            android:layout_toRightOf="@+id/leftTextView"
            android:ellipsize="end"
            android:lines="1"
            android:text="Right Text" />
    
    </RelativeLayout>
    
    
    

    然而,解决方案的局限性在于必须在maxWidth属性中指定固定值。因此,它将在不同的屏幕大小上显示不同的外观。不过,在大多数情况下,你们不会面临这个问题


    此外,对于在单行中显示长文本视图,android:ellipsize=“marquee”是一个不错的选择。因为它将水平滚动您的视图。但别忘了在代码中编写这个
    textView.setSelected(true)
    ,让它正常工作

    您可以通过
    TableLayout
    shrinkColumns
    属性来存档此布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
        <!-- Row 1 -->
        <TableLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:shrinkColumns="1">
    
            <TableRow
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_vertical">
    
                <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/ic_launcher"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="end"
                        android:text="leftText"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="none"
                        android:text="rightText"/>
            </TableRow>
    
        </TableLayout>
    
    
        <!-- Row 2 -->
        <TableLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:shrinkColumns="1">
    
            <TableRow
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_vertical">
    
                <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/ic_launcher"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="end"
                        android:text="leftTextPrettyLongButNotHuge"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="none"
                        android:text="rightText"/>
            </TableRow>
    
        </TableLayout>
    
        <!-- Row 3 -->
        <TableLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:shrinkColumns="1">
    
            <TableRow
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_vertical">
    
                <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/ic_launcher"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="end"
                        android:text="leftTextWhichIsIncrediblyLongBlahBlahBlahBlah"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="none"
                        android:text="rightText"/>
            </TableRow>
    
        </TableLayout>
    
    </LinearLayout>
    
    
    

    虽然权重允许您提到的“负增长”,但它也会在不需要时扩展字段以填充宽度。最后,将
    rightextView
    固定到父视图的右侧/末端。从功能上看,它似乎与我在问题中尝试的第2部分中的相同。@伊曼纽尔·莫克林(Emanuel Moecklin)@Stonz2如果我使用的是相对布局而不是线性布局,那该怎么办?@Stonz2这是我的测试发现的,而Android的屏幕大小差异如此之大(加上纵向和横向)固定宽度绝对不是一个理想的方法。我已经告诉过你,当你知道一些固定宽度大小的视图时,这会起作用。否则,您可以按照@whizzle的建议以编程方式完成。感谢您的回答-我尝试了一下,效果很好,但nshmura的方法也可以,但它完全是XML的,不依赖于子类化。在我为重复标记辩护时,另一个问题在我问我的问题时没有答案。而且,它的标题很糟糕,这可能是我一开始没有意识到它存在的原因。垂直布局能做到这一点吗?我需要将TableRow中的项目垂直对齐,并设置android:shrinkColumns=“0”以缩小第一个视图。设置
    android:shrinkColumns=“0”
    工作正常。如何使用ConstraintLayout实现这一点?
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
        <!-- Row 1 -->
        <TableLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:shrinkColumns="1">
    
            <TableRow
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_vertical">
    
                <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/ic_launcher"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="end"
                        android:text="leftText"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="none"
                        android:text="rightText"/>
            </TableRow>
    
        </TableLayout>
    
    
        <!-- Row 2 -->
        <TableLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:shrinkColumns="1">
    
            <TableRow
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_vertical">
    
                <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/ic_launcher"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="end"
                        android:text="leftTextPrettyLongButNotHuge"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="none"
                        android:text="rightText"/>
            </TableRow>
    
        </TableLayout>
    
        <!-- Row 3 -->
        <TableLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:shrinkColumns="1">
    
            <TableRow
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_vertical">
    
                <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/ic_launcher"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="end"
                        android:text="leftTextWhichIsIncrediblyLongBlahBlahBlahBlah"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="none"
                        android:text="rightText"/>
            </TableRow>
    
        </TableLayout>
    
    </LinearLayout>