带有长文本的TextView将其他视图推离屏幕

Com*_*ler 8 android android-layout

我正在尝试实现以下布局:

+----------------------------------------+
| [icon] [text] [icon]                   |
+----------------------------------------+
| [icon] [very loooooooooooooooooo [icon]|
|         oooooooooooooooong text]       |
+----------------------------------------+
Run Code Online (Sandbox Code Playgroud)

当文本很短时,右边的图标需要在文本旁边(不是右对齐).当文本很长时,我需要包装文本.

我曾尝试使用LinearLayout和RelativeLayout,但是当我有一个长文本时,图标仍然被推出.这是我尝试过的布局:

LinearLayout中:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="horizontal">

    <TextView
        android:id="@+id/left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="left"/>

    <TextView
        android:id="@+id/middle"
        android:text="a long long string, a long long string, a long long string, a long long string, a long long string, a long long string, "
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#D0E198"/>

    <TextView
        android:id="@+id/right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="right"/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

RelativeLayout的:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content">

    <TextView
        android:id="@+id/left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="left"/>

    <TextView
        android:id="@+id/middle"
        android:text="a long long string, a long long string, a long long string, a long long string, a long long string, a long long string, "
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#D0E198"
        android:layout_toRightOf="@id/left"/>

    <TextView
        android:id="@+id/right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="right"
        android:layout_toRightOf="@id/middle"/>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,右侧图标都会被推出屏幕.

我也尝试过LinearLayout,左右视图的layout_weight ="1",中间视图的0.这会将两个图标都推离屏幕.

Chr*_*lla 6

我知道这是该线程的较晚答案,但我找到了解决方案并想与其他人分享。

\n

要解决此问题,您应该使用 ConstraintLayout:

\n
<androidx.constraintlayout.widget.ConstraintLayout\nxmlns:android="http://schemas.android.com/apk/res/android"\nxmlns:app="http://schemas.android.com/apk/res-auto"\nandroid:layout_width="match_parent"\nandroid:layout_height="match_parent">\n\xe2\x80\x8b\n<ImageView\n    android:id="@+id/iconStart"\n    android:layout_width="wrap_content"\n    android:layout_height="wrap_content"\n    android:src="@drawable/unread_circuler_dot"\n    app:layout_constraintEnd_toStartOf="@id/text"\n    app:layout_constraintHorizontal_bias="0"\n    app:layout_constraintHorizontal_chainStyle="packed"\n    app:layout_constraintStart_toStartOf="parent"\n    app:layout_constraintTop_toTopOf="parent" />\n\xe2\x80\x8b\n<TextView\n    android:id="@+id/text"\n    android:layout_width="0dp"\n    android:layout_height="wrap_content"\n    android:ellipsize="end"\n    android:maxLines="2"\n    android:text="Very long text"\n    android:textColor="@color/white"\n    app:layout_constraintEnd_toStartOf="@id/iconEnd"\n    app:layout_constraintHorizontal_chainStyle="packed"\n    app:layout_constraintStart_toEndOf="@id/iconStart"\n    app:layout_constraintTop_toTopOf="parent"\n    app:layout_constraintWidth_default="wrap" />\n\xe2\x80\x8b\n<ImageView\n    android:id="@+id/iconEnd"\n    android:layout_width="wrap_content"\n    android:layout_height="wrap_content"\n    android:src="@drawable/unread_circuler_dot"\n    app:layout_constraintEnd_toEndOf="parent"\n    app:layout_constraintHorizontal_chainStyle="packed"\n    app:layout_constraintStart_toEndOf="@id/text"\n    app:layout_constraintTop_toTopOf="parent" />\n\xe2\x80\x8b\n\xe2\x80\x8b\n</androidx.constraintlayout.widget.ConstraintLayout>\n
Run Code Online (Sandbox Code Playgroud)\n

此修复的关键是行app:layout_constraintWidth_default="wrap"\n来自 Google 本身的相关信息:

\n

Wrap :\n仅将视图展开到适合其内容所需的程度,但如果约束需要,仍然允许视图小于该视图。因此,这与使用 Wrap Content(上面)的区别在于,将宽度设置为 Wrap Content 会强制宽度始终与内容宽度完全匹配;而使用匹配约束并将layout_constraintWidth_default设置为wrap也允许视图小于内容宽度。

\n

更多信息可以在这里找到

\n

更新!!

\n

由于app:layout_constraintWidth_default="wrap"已被弃用,实现相同效果的主要方法是将其与

\n
android:layout_width="wrap_content"\napp:layout_constrainedWidth="true"\n
Run Code Online (Sandbox Code Playgroud)\n


Com*_*ler 5

这是我为实现自己想要的目的而做的事情:

我在中间的 TextView中添加了layout_weight =“ 1”

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="horizontal">

    <TextView
        android:id="@+id/left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="left"/>

    <WrapWidthTextView
        android:id="@+id/middle"
        android:text="a long long string, a long long string, a long long string, a long long string, a long long string, a long long string, "
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#D0E198"
        android:layout_weight="1"/>

    <TextView
        android:id="@+id/right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="right"/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

但是,当中间文本很短时,它将仍然占据整个空白的中间空间,并将右边的TextView一直推到右边。我必须继承TextView:

public class WrapWidthTextView
  extends TextView {

    // constructors here

    @Override protected void onMeasure (final int widthMeasureSpec, final int heightMeasureSpec) {
        super.onMeasure (widthMeasureSpec, heightMeasureSpec);

        Layout layout = getLayout ();
        if (layout != null) {
            int width = (int) Math.ceil (getMaxLineWidth (layout))
                        + getCompoundPaddingLeft () + getCompoundPaddingRight ();
            int height = getMeasuredHeight ();
            setMeasuredDimension (width, height);
        }
    }

    private float getMaxLineWidth (Layout layout) {
        float max_width = 0.0f;
        int lines = layout.getLineCount ();
        for (int i = 0; i < lines; i++) {
            if (layout.getLineWidth (i) > max_width) {
                max_width = layout.getLineWidth (i);
            }
        }
        return max_width;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用WrapWidthTextView,当文本较短时,它将缩小视图以适合文本。

这就解决了我的问题。我希望这也会对其他人有所帮助。


Eva*_*hir 3

使用第一个布局,但向中间文本视图添加权重。

例子:

 <TextView
        android:id="@+id/middle"
        android:text="a long long string, a long long string, a long long string, a long long string, a long long string, a long long string, "
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:background="#D0E198"/>
Run Code Online (Sandbox Code Playgroud)

确保使用 0dp 作为宽度!

注意:此答案适用于您希望图标右对齐的情况。我不确定这就是你所需要的。

  • 谢谢你的建议。我已经尝试过了。但我不希望图标右对齐。当文本字段很短时,它需要位于文本字段的旁边。我已经更新了我的问题以澄清这一点。 (3认同)