Android TextView截断优先或压缩电阻

我在屏幕上水平放置3个视图(固定大小的图像和2个单行文本视图: leftTextViewrightTextView ),我试图让rightTextViewleftTextViewrightTextViewleftTextView ,但是如果宽度这两个标签都会超出屏幕大小,截断leftTextiew

所需function的例子:

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

究竟发生了什么:

 |img|leftText|rightText| ||(end of screen) |img|leftTextPrettyLongButNotHuge|rightT|| |img|leftTextWhichIsIncrediblyLongBlahBl|| 

目前,如果两个文本视图的大小都超过了视图的宽度,那么rightTextView最终会被rightTextView以腾出空间,尽pipe我在android:ellipsize="end"设置了android:ellipsize="end"

有没有办法让leftTextView有一个“截断优先级”,说应该截断,如果它会导致其他意见不适合? 或者,另一方面,我可以设置正确的rightTextView有一个“抗压缩”,以防止被挤压为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> 

我试过的东西:

  1. leftTextView ,添加一个toStartOf / toLeftOf rightTextView (崩溃应用程序)
  2. 而不是将右侧的leftTextViewalignment到左侧的rightTextView右侧,将leftTextView翻转并将左侧的rightTextViewalignment到leftTextView的开始/左侧。 这将导致rightTextView被锚定到屏幕的末尾,而不是直接位于左侧的leftTextView的右侧。 最后看起来如何的例子:

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

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

Solutions Collecting From Web of "Android TextView截断优先或压缩电阻"

您可以通过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> 

在这里输入图像说明

这就是我所做的:

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

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

我想你会需要做一个自定义的布局。 这对于我所做的示例非常有效,它满足您在上面发布的所有要求,但是您需要添加更多的math代码来计算layout_margins和padding。

关于这里发生了什么的基本思路是我将LinearLayout分类,并在onMeasure阶段中检查以确保正确的视图可以select占用尽可能多的空间。 请注意,我必须重新测量正确的视图,而不是只测量宽度,因为linearlayout不会给它足够的空间。 一旦你有多less空间正确的视图占用,检查,看中间视图(称为leftView …对不起)占用更多的空间比你想要的。 如果是这样,只要给它留下的空间。

根据你的要求,它在一个RecyclerView …我知道你说你想要一个纯粹的XML解决scheme,但你会得到更好的性能,如果你在代码解决它作为XML 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> 

在这里输入图像说明

只需使用android:maxWidth属性到左边的textView。 所以,你的左视图将永远不会超过这个限制。 而且总会有空间为你的正确的看法。

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

布局预览

但是,解决scheme的限制是你必须在maxWidth属性中给定一个固定值。 所以,它会在不同的屏幕尺寸上显示不同的外观。 虽然,在大多数情况下,你不会面临问题。

此外,在单行显示长android:ellipsize="marquee"是不错的select。 因为它会滚动你的视图水平。 但是不要忘记在你的代码中写这个textView.setSelected(true)来使它工作。 详情