代码之家  ›  专栏  ›  技术社区  ›  Felix

两个文本视图并排,只有一个要省略?

  •  63
  • Felix  · 技术社区  · 14 年前

    我想要两个 TextView 元素并排出现(在列表项中),一个与左侧对齐,一个与右侧对齐。比如:

    |<TextView>               <TextView>|
    

    (the | 表示屏幕的末端)

    但是, 文本框 左侧的内容可能太长,无法在屏幕上显示。在这种情况下,我想让它椭圆化,但仍然显示整个右侧 文本框 . 比如:

    |This is a lot of conte...<TextView>|
    

    我尝试过很多次,都用了 LinearLayout RelativeLayout 唯一的解决办法是 相对布局 然后放一个 marginRight 在左边 文本框 大到可以清理右边 文本框 . 但正如你所能想象的,这并不是最佳的。

    还有其他的解决办法吗?

    最后, 线性布局 解决方案:

    <LinearLayout
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:orientation="horizontal"
        >
        <TextView
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_weight="1"
            android:ellipsize="end"
            android:inputType="text"
            />
        <TextView
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_weight="0"
            android:layout_gravity="right"
            android:inputType="text"
            />
    </LinearLayout>
    

    旧的, TableLayout 解决方案:

    <TableLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:stretchColumns="1"
        android:shrinkColumns="0"
        >
        <TableRow>
            <TextView android:id="@+id/title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:singleLine="true"
                />
            <TextView android:id="@+id/date"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:singleLine="true"
                android:ellipsize="none"
                android:gravity="right"
                />
        </TableRow>
    </TableLayout>
    
    5 回复  |  直到 8 年前
        1
  •  15
  •   Stephen Rauch Afsar Ali    8 年前

    使用tablelayout并将两个textview都放在表行中,尝试一下。我没试过

        2
  •  19
  •   capecrawler    14 年前

    只是一个想法,为什么不先在XML布局中声明右侧的textView,并将其宽度设置为wrap内容, android:layout_alignParentRight="true" android:gravity="right" . 然后声明左侧的textView,将其宽度设置为fill parent, android:layout__toLeftOf =右侧文本视图的ID具有 RelativeView 作为根视图。

    首先声明右textView,它所需的宽度将首先计算并占用视图,而左侧的textView将占用视图的剩余空间。

    我还没有试过这个,尽管它可能会给你一些想法。

    [更新]

    我尝试创建一个XML资源布局…不知怎的它起作用了…

    <RelativeLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content">
      <TextView 
        android:id="@+id/right"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:text="right"
        >
      </TextView>
      <TextView 
        android:id="@+id/left"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@id/right"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:lines="1"
        android:singleLine="true"
        android:maxLines="1"
        android:text="too looooooooooong ofskgjo sdogj sdkogjdfgds dskjgdsko jgleft"
        >
      </TextView>
    </RelativeLayout>
    
        3
  •  16
  •   Community CDub    8 年前

    线性布局的答案对我来说也是同样的问题。作为一个单独的答案发布,因为不清楚是什么做的,也不为提问者工作。

    一个区别。对于我来说,TableLayout不太理想,因为我有两行数据,我希望底行的行为与这个问题描述的一致,而顶行的行为跨越这个区域。另一个问题回答了这个问题: Colspan in TableLayout 但线性布局更简单。

    虽然我花了点时间才把宽度调整好。我包括了Android的线头调整使用 0dp 性能缩放项的宽度。

    <LinearLayout
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:orientation="horizontal"
        >
        <TextView
            android:layout_height="wrap_content"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:ellipsize="end"
            android:inputType="text"
            />
        <TextView
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_weight="0"
            android:layout_gravity="right"
            android:inputType="text"
            />
    </LinearLayout>
    
        4
  •  1
  •   Gábor    9 年前

    关于这个问题有很多答案,实际上是等价的,重复的问题。建议的方法通常有效,有点像。把它放进 LinearLayout 把整个包裹在一个额外的 RelativeLayout ,使用 TableLayout ;所有这些似乎都能解决更简单的布局问题,但如果您需要这两个 TextView 在更复杂的内容中,或者相同的布局将被重用,例如, RecyclerView 事情很快就坏了。

    我发现唯一有效的解决方案 总是, 不管你把它放在哪个更大的布局中,它都是一个定制的布局。它的实现非常简单,而且尽可能的精益,它会保持布局合理的平坦,很容易维护,所以从长远来看,我认为这是解决问题的最佳方案。

    public class TwoTextLayout extends ViewGroup {
    
      public TwoTextLayout(Context context) {
        super(context);
      }
    
      public TwoTextLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
      }
    
      public TwoTextLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
      }
    
      @Override
      protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int count = getChildCount();
        if (count != 2)
          throw new IllegalStateException("TwoTextLayout needs exactly two children");
    
        int childLeft = this.getPaddingLeft();
        int childTop = this.getPaddingTop();
        int childRight = this.getMeasuredWidth() - this.getPaddingRight();
        int childBottom = this.getMeasuredHeight() - this.getPaddingBottom();
        int childWidth = childRight - childLeft;
        int childHeight = childBottom - childTop;
    
        View text1View = getChildAt(0);
        text1View.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST));
        int text1Width = text1View.getMeasuredWidth();
        int text1Height = text1View.getMeasuredHeight();
    
        View text2View = getChildAt(1);
        text2View.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST));
        int text2Width = text2View.getMeasuredWidth();
        int text2Height = text2View.getMeasuredHeight();
    
        if (text1Width + text2Width > childRight)
          text1Width = childRight - text2Width;
    
        text1View.layout(childLeft, childTop, childLeft + text1Width, childTop + text1Height);
        text2View.layout(childLeft + text1Width, childTop, childLeft + text1Width + text2Width, childTop + text2Height);
      }
    }
    

    实现不可能简单,它只测量两个文本(或者任何其他子视图,实际上),如果它们的组合宽度超过布局宽度,则会减小第一个视图的宽度。

    如果您需要修改,例如将第二个文本与第一个文本的基线对齐,您也可以轻松地解决这一问题:

    text2View.layout(childLeft + text1Width, childTop + text1Height - text2Height, childLeft + text1Width + text2Width, childTop + text1Height);
    

    或任何其他解决方案,如缩小与第一个视图相关的第二个视图,右对齐等。

        5
  •  0
  •   Maragues    14 年前

    为什么不在右文本视图上加一个左边距?我用这种方法

    |<TextView>       <ImageButton>|
    

    而且它是有效的。