【问题标题】:2 TextViews, left with ellipsis, right with nowrap, single line2个TextViews,左边是省略号,右边是nowrap,单行
【发布时间】:2014-10-31 08:21:15
【问题描述】:

这是我第一次在这个论坛上发帖,希望一切都会好起来:)

我正在为我所在城市的公共交通开发一款 Android 应用。

Here is what I have

[ |short destination   ||next departure| ]
[ |way too long dest...||next departure| ]

Here is what I want:

[ |short destination||next departure|    ]
[ |way too long dest...||next departure| ]

这里有一个更完整的例子:s28.postimg.org/5gejnvfd9/actual2.png

奇怪的彩色背景只是为了轻松识别布局/文本视图。您也可以忽略棕色线(没关系)。

基本上,我想要具有可变长度的目的地[红色背景],并且在其右侧,我想要第一个出发时间[绿色背景]。一切都在一条线上。

我需要始终完全显示第一个出发信息(nowrap)。目的地可以用省略号 (...) 包裹。 [可选问题,如何将省略号 '...' 替换为 '.' ?]

这是迄今为止我最好的工作代码:

    <RelativeLayout 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/txtTitleDestination"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_toLeftOf="@+id/txtTitleFirstDeparture"
            android:background="#FF0000"
            android:ellipsize="end"
            android:maxLines="1"
            android:padding="0dp"
            android:scrollHorizontally="true"
            android:textSize="18sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/txtTitleFirstDeparture"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="0dp"
            android:layout_marginRight="0dp"
            android:layout_alignParentRight="true"
            android:background="#00FF00"
            android:ellipsize="none"
            android:maxLines="1"
            android:padding="0dp"
            android:textSize="18sp"
            android:textStyle="bold" 
            />

    </RelativeLayout>

我尝试过 TableLayout 和 LinearLayour 而不是 RelativeLayout,但没有成功:(

知道我该怎么做吗?

提前致谢!

卢鲁克斯

[已解决] 只需轻轻修改 valberos 答案:

titleDestination.post(new Runnable() {
        @Override
        public void run() {             
            int widthTextViewDeparture = measureTextWidthTextView(titleFirstTime, pContext);
            int widthTextViewDestination = titleDestination.getWidth();
            int widthTextViewParent = rl_parent.getWidth();
            if(widthTextViewDestination + widthTextViewDeparture > widthTextViewParent) {
                titleDestination.setWidth(widthTextViewParent - widthTextViewDeparture);
                titleDestination.setEllipsize(TruncateAt.END);
                titleDestination.setHorizontallyScrolling(true);
            }
        }
    });

仅在必要时设置省略号会使文本正确截断。

Before: 
Lingolsheim Thiergaten --> Lingolsheim...     [1'23"] 21h23

With the modification:
Lingolsheim Thiergaten --> Lingolsheim Thi... [1'23"] 21h23

再次感谢:)

【问题讨论】:

  • 这里有一个更完整的例子:s28.postimg.org/5gejnvfd9/actual2.png
  • 您必须了解的是,内容是从 WebService 中动态检索的。因此,我事先不知道目的地名称有多大,所以我肯定需要动态的“目的地名称”TextView(就宽度而言),我不希望这个“隐藏”右边文本视图。

标签: android textview ellipsis nowrap


【解决方案1】:

您不需要以编程方式执行此操作,ConstraintLayout 是一种魔法!

只需使用此代码

app:layout_constraintHorizontal_bias="0"左对齐视图

app:layout_constrainedWidth="true" 自动换行

<?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="wrap_content"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:maxLines="1"
        app:layout_constrainedWidth="true"
        app:layout_constraintHorizontal_bias="0"
        app:layout_constraintEnd_toStartOf="@id/rightText"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="|short destination|" />

    <TextView
        android:id="@+id/rightText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/leftText"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="|next departure|" />

</androidx.constraintlayout.widget.ConstraintLayout>

这是结果

【讨论】:

    【解决方案2】:

    我找到了一种使用线性布局的方法,诀窍是不要忘记线性布局的 width="wrap_content",希望它可以提供帮助。

    <LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    
    
    <TextView
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:ellipsize="end"
        android:singleLine="true" />
    
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true" />
    

    【讨论】:

      【解决方案3】:

      要执行您的要求,您必须根据第二个视图的文本宽度动态调整第一个视图的宽度。

      //代码

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.test);
      
          final TextView tv_1 = (TextView) findViewById(R.id.tv_1);
          tv_1.post(new Runnable() {
              @Override
              public void run() {
                  View rl_parent = findViewById(R.id.rl_parent);
                  TextView tv_2 = (TextView) findViewById(R.id.tv_2);
                  int widthTextView2 = measureTextWidthTextView(tv_2);
                  if(tv_1.getWidth() + widthTextView2 > rl_parent.getWidth()) {
                      tv_1.setWidth(tv_1.getWidth() - widthTextView2);
                  }
              }
          });
      }
      
      private int measureTextWidthTextView(TextView textView) {
          int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(getScreenWidth(), View.MeasureSpec.AT_MOST);
          int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
          textView.measure(widthMeasureSpec, heightMeasureSpec);
          return textView.getMeasuredWidth();
      }
      
      private int getScreenWidth() {
          WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
          Display display = wm.getDefaultDisplay();
          Point size = new Point();
          display.getSize(size);
          return size.x;
      }
      

      //布局

      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="300dp"
          android:layout_height="match_parent"
          android:orientation="vertical">
      
          <RelativeLayout
              android:id="@+id/rl_parent"
              android:layout_width="match_parent"
              android:layout_height="40dp"
              android:background="#348D63">
      
              <TextView
                  android:id="@+id/tv_1"
                  android:layout_width="wrap_content"
                  android:layout_height="match_parent"
                  android:background="#BD160B"
                  android:gravity="center_vertical"
                  android:maxLines="1"
                  android:paddingLeft="10dp"
                  android:paddingRight="10dp"
                  android:text="Elsau Elsau Elsau Elsau Elsau Elsau Elsau"
                  android:textStyle="bold" />
      
              <TextView
                  android:id="@+id/tv_2"
                  android:layout_width="wrap_content"
                  android:layout_height="match_parent"
                  android:layout_toRightOf="@+id/tv_1"
                  android:gravity="center_vertical"
                  android:minWidth="50dp"
                  android:paddingLeft="10dp"
                  android:paddingRight="10dp"
                  android:text="[11:30 14:23]"
                  android:textStyle="bold" />
      
          </RelativeLayout>
      
          <!-- Rest of the layout -->
      
      </LinearLayout>
      

      使用 android:maxLines="1" 而不是 android:singleLine="true" 来消除丑陋的圆点 - 正如我在示例中所做的那样。

      另外,我建议您在“时间”部分使用include,而不是重复两次 TextViews。我只是这样做以保持示例简单。

      【讨论】:

      • 嗨 valbertos,谢谢,但我尝试了您提出的两个 RelativeLayout,但如果左侧 TextView 太长,第一个不会让右侧 TextView 可见。第二个RelativeLayout对于左侧TextView有一个固定的宽度,这是不行的,因为它有一个动态大小。
      • 我不太了解你。再试一次,我已经修改了我的问题;)
      • 好吧,实际上你似乎明白我的意思了:) 我想根据右边调整左边 TextView 的宽度,这样右边总是在 1 行上完全显示。但我认为我可以从 xml 视图中做到这一点。我会尽快尝试您的解决方案 :) 谢谢。
      • 是的,它正在工作:) 非常感谢!知道它是否可以直接使用 xml View 吗?我觉得它可以在 HTML/css 中完成(1 个表格,2 个列,第一个省略号,第二个 nowrap)。无论如何,非常感谢!很棒的论坛 =) 干杯!
      • 不客气!我不认为仅仅通过布局就可以实现,因为布局系统不支持如此复杂的计算。 :)
      【解决方案4】:

      也许您应该使用 LinearLayout 而不是 RelativeLayout 并使用 layout_weight 属性。

      <LinearLayout android:orientation="horizontal" ...>
          <TextView android:id="@+id/txtTitleDestination" android:layout_width="wrap_content" ... />
          <TextView android:id="@+id/txtTitleFirstDeparture" android:layout_width="0dp" android:layout_weight="1" ... />
      </LinearLayout>
      

      【讨论】:

      • 嗨 pomber,嗯,谢谢,这也是我的第一个想法,但它不起作用:如果左边的 TextView 太长,右边的不可见......
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 2020-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多