【问题标题】:Two TextViews side by side, only one to ellipsize?两个TextView并排,只有一个椭圆?
【发布时间】:2010-09-24 08:03:38
【问题描述】:

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

|<TextView>               <TextView>|

| 代表屏幕的末端)

但是,左侧的TextView 的内容可能太长而无法在屏幕上显示。在这种情况下,我想让它变成椭圆形,但仍然显示整个右边TextView。比如:

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

我对此进行了多次尝试,同时使用LinearLayoutRelativeLayout,我想出的唯一解决方案是使用RelativeLayout 并在左侧放置marginRight TextView big足以清除正确的TextView。但是,正如您可以想象的那样,这并不是最佳选择。

还有其他解决方案吗?

最终,LinearLayout 解决方案:

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

【问题讨论】:

  • 我也想对答案投票。 :)

标签: android android-layout


【解决方案1】:

只是一个想法,为什么不在xml布局中首先声明右侧的textview并将其宽度设置为包装内容,android:layout_alignParentRight="true"android:gravity="right"。然后声明左边的textview,设置它的宽度为填充父视图,android:layout__toLeftOf={右边的textview的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>

【讨论】:

  • 刚试过,不行。原因是 RelativeLayout 允许其子级重叠,因此最终左侧 TextView 出现在右侧 TextView 的“下方”。
  • 我添加了一个示例 xml 布局。希望这是您正在寻找的。干杯!
  • 关于左侧TextView 出现在右侧TextView 的“下方”,如果您明确指定布局应位于右侧TextView 的左侧,则不会发生这种情况。属性android:layout_toLeftOf="@id/right" 将实现这一目标。希望这会有所帮助。
  • 有趣,感谢您的解决方案。但是,我最终找到了一个基于LinearLayout 的解决方案(对我来说)效果更好。我将其发布在问题正文中。
  • 谢谢。我必须使用 RelativeLayout 所以 LinearLayout 解决方案对我不起作用。
【解决方案2】:

LinearLayout 的答案对我同样适用。发布为单独的答案,因为不清楚什么对提问者有用,什么没用。

一个区别。 TableLayout 对我来说不太理想,因为我有两行数据,我希望底行的行为与此问题描述的一样,而顶行则跨越该区域。该问题已在另一个 SO 问题中得到解答:Colspan in TableLayout,但 LinearLayout 更简单。

虽然获得正确的宽度花了我一点时间。我在缩放项上包含了使用0dp 宽度的android lint 调整以提高性能。

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

【讨论】:

  • 这是最好的答案,因为从性能角度来看,对于这种情况,最好使用 LinearLayout 而不是 Table(或 Relative)
【解决方案3】:

使用 TableLayout 并将 TextView 都放在表格行中,试一试。我没试过

【讨论】:

  • 谢谢,这最终奏效了。我已编辑问题以包含我找到的解决方案。
【解决方案4】:

关于 SO 有很多答案,实际上是相同的、重复的问题。建议的方法通常会起作用。将其放入LinearLayout,将整个包裹在一个额外的RelativeLayout 中,使用TableLayout;所有这些似乎都解决了一个更简单的布局,但如果你需要这两个 TextViews 在更复杂的东西中,或者相同的布局将被重用,例如 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】:

    为什么不在右边的TextView上加一个左边距呢?我正在使用这种方法

    |<TextView>       <ImageButton>|
    

    它有效。

    【讨论】:

    • 它可能对您有用,因为您的 ImageButton 始终具有相同的宽度。我的有所不同,所以它对我不起作用。
    • 很高兴 TableLayout 为您工作 :) 这是一个类似的问题,带有自调节按钮 stackoverflow.com/questions/3530182/…
    【解决方案6】:

    ConstraintLayout的解决方案

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="8dp">
    
        <TextView
            android:id="@+id/leftText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:maxLines="1"
            app:layout_constraintEnd_toStartOf="@id/rightText"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="This is a lot of content that should be cut" />
    
        <TextView
            android:id="@+id/rightText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="Right text" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    【讨论】:

      【解决方案7】:

      当我遇到类似的问题时,我做了以下事情: 我需要:

      |<TextView, may be long> <TextViewFixedSize>      |
      |<TextView, may be longer ...> <TextViewFixedSize>|
      |<TextViewLong> <TextViewFixedSize>               |
      

      您可以使用这样的解决方案:

      <androidx.constraintlayout.widget.ConstraintLayout
          android:id="@+id/layoutRecommendedServiceDescription"
          android:layout_width="0dp"
          android:layout_height="match_parent"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="@+id/textViewRecommendedServiceTitle"
          app:layout_constraintTop_toBottomOf="@id/textViewRecommendedServiceTitle">
          <TextView
              android:id="@+id/textViewRecommendedService1"
              android:layout_width="wrap_content"
              android:layout_height="match_parent"
              android:ellipsize="end"
              android:lines="1"
              android:maxLines="1"
              app:layout_constrainedWidth="true"
              app:layout_constraintHorizontal_bias="0"
              app:layout_constraintHorizontal_chainStyle="packed"
              app:layout_constraintEnd_toStartOf="@+id/textViewRecommendedServicePopular"
              app:layout_constraintStart_toStartOf="parent"
              tools:text="Long text"
              tools:visibility="visible" />
          <TextView
              android:id="@+id/textViewRecommendedServicePopular"
              android:layout_width="wrap_content"
              android:layout_height="match_parent"
              android:layout_marginStart="8dp"
              android:lines="1"
              android:text="@string/services_popular"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toEndOf="@+id/textViewRecommendedService1"
              app:layout_goneMarginStart="0dp"
              tools:visibility="visible" />
      </androidx.constraintlayout.widget.ConstraintLayout>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-01-19
        • 2011-03-14
        • 1970-01-01
        • 1970-01-01
        • 2013-09-09
        • 2015-11-02
        • 1970-01-01
        相关资源
        最近更新 更多