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

时间:2016-08-09 21:05:41

标签: android xml textview truncation

我在屏幕上水平布置了3个视图(固定大小的图像和2个单行文本视图:leftTextViewrightTextView)并且我正在尝试获取{{1要拥抱rightTextView,但如果两个标签的宽度超过屏幕尺寸,请截断leftTextView

所需功能的示例:

leftTextiew

实际发生了什么:

|img|leftText|rightText|                ||(end of screen)
|img|leftTextMedium|rightText|          ||
|img|leftTextTooLongSoTrunc...|rightText||

目前,如果两个文字视图的尺寸都超过了视图的宽度,那么即使我在|img|leftText|rightText| ||(end of screen) |img|leftTextPrettyLongButNotHuge|rightT|| |img|leftTextWhichIsIncrediblyLongBlahBl|| 上设置rightTextViewandroid:ellipsize="end"最终也会被压缩以腾出空间

有没有办法让leftTextView具有“截断优先级”,表示如果它会导致其他视图不适合它应截断?或者另一方面,我可以将leftTextView设置为具有“抗压性”,以防止它被压扁以为rightTextView腾出空间吗?这是我的XML示例:

leftTextView

我尝试过的事情:

  1. <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> 中,添加leftTextView / toStartOf toLeftOf(崩溃应用)
  2. 不要将rightTextViewrightTextView的结尾/右对齐,而是将其翻转并将leftTextViewleftTextView的开头/左侧对齐。这会导致rightTextView锚定到屏幕的末尾,而不是直接位于rightTextView的右侧。最终看起来如何:

    leftTextView
  3. 即使我设置|img|leftText |rightText|| |img|leftTextMedium |rightText|| |img|leftTextTooLongSoTrunc...|rightText|| 只是为了确保android:minWidth="25dp"部分至少可见(我不想这样做,因为这个文本长度是变量的)它仍然会压缩宽度以便为rightTextView腾出空间。

  4. 根据Emanuel Moecklin的回答,我尝试用leftTextView换行并在LinearLayout上设置权重。结果在视觉上与我在#2中尝试的相同。

4 个答案:

答案 0 :(得分:10)

您可以按TableLayoutshrinkColumns属性归档此布局。

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

enter image description here

答案 1 :(得分: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,而另一个没有给予重量,第三个文字字段   没有重量不会增长,只会占据所需的面积   它的内容。

https://developer.android.com/guide/topics/ui/layout/linear.html#Weight

没有详细说明没有空间填充但没有足够空间用于所有视图的情况。对所提到的文档的一种解释是,没有权重的字段(在这种情况下为rightTextView)将占用其内容所需的区域,而具有权重的字段(在这种情况下为leftTextView)将“增长”(如在负面中)增长),这正是发生的事情。

答案 2 :(得分:1)

我认为您需要制作自定义布局。这适用于我制作的样本,它符合您在上面发布的所有要求,但您需要添加更多数学代码来解释layout_margins和padding。

这里发生了什么的基本思路是我将LinearLayout子类化,在onMeasure传递中,我检查以确保右视图可以选择占用尽可能多的空间。请注意,我必须重新测量正确的视图,而不仅仅是获得测量的宽度,因为linearlayout不会给它足够的空间。一旦你有正确的视图占用多少空间,检查中间视图(称为leftView ...对不起)是否占用了比你想要的更多的空间。如果确实如此,只需给它剩下的空间。

根据你在RecyclerView中的要求...我知道你说你想要一个纯xml解决方案,但如果你在代码中解决它xn 1你会得到更好的性能。可能是不可能的2.需要更多的计算而不是直接自己动手。

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>

enter image description here

答案 3 :(得分:0)

只需在左侧textView中使用android:maxWidth属性即可。所以,你的左视图永远不会超过这个限制。你的正确观点总是有空间。

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

Preview of layout

但是,解决方案的限制是你必须在maxWidth属性中给出固定值。因此,它会在不同的屏幕尺寸上显示不同的外观。但是,在大多数情况下,您不会遇到问题。

另外,在单行android:ellipsize="marquee"中显示长textView是个不错的选择。因为它会水平滚动您的视图。但是不要忘记在代码中写下textView.setSelected(true)以使其正常工作。 Detail