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

时间:2015-05-21 00:13:32

标签: android android-layout

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

+----------------------------------------+
| [icon] [text] [icon]                   |
+----------------------------------------+
| [icon] [very loooooooooooooooooo [icon]|
|         oooooooooooooooong text]       |
+----------------------------------------+

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

我曾尝试使用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>

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>

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

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

8 个答案:

答案 0 :(得分:5)

以下是我为实现目标所做的工作:

我将 layout_weight =“1”添加到中间 TextView

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

但是,当中间文本很短时,它仍将占据整个空的中间空间并将右侧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;
    }
}

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

这解决了我的问题。我希望这也有助于其他人。

答案 1 :(得分:2)

将maxWidth设置为文本字段。它不会变得更大。您还可以将maxLines设置为停止换行到新行。

答案 2 :(得分:2)

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

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

<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
​
<ImageView
    android:id="@+id/iconStart"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/unread_circuler_dot"
    app:layout_constraintEnd_toStartOf="@id/text"
    app:layout_constraintHorizontal_bias="0"
    app:layout_constraintHorizontal_chainStyle="packed"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
​
<TextView
    android:id="@+id/text"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:ellipsize="end"
    android:maxLines="2"
    android:text="Very long text"
    android:textColor="@color/white"
    app:layout_constraintEnd_toStartOf="@id/iconEnd"
    app:layout_constraintHorizontal_chainStyle="packed"
    app:layout_constraintStart_toEndOf="@id/iconStart"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintWidth_default="wrap" />
​
<ImageView
    android:id="@+id/iconEnd"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/unread_circuler_dot"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_chainStyle="packed"
    app:layout_constraintStart_toEndOf="@id/text"
    app:layout_constraintTop_toTopOf="parent" />
​
​
</androidx.constraintlayout.widget.ConstraintLayout>

此修补程序的关键是第app:layout_constraintWidth_default="wrap"行 有关Google本身的信息:

包装仅根据需要扩展视图以适合其内容,但如果约束需要,则仍允许视图缩小。因此,这与使用Wrap Content(上方)之间的区别在于,将宽度设置为Wrap Content会强制宽度始终与内容宽度完全匹配;而将Match Constraints与layout_constraintWidth_default设置为wrap相比,还可以使视图小于内容宽度。

可以找到更多信息here

答案 3 :(得分:1)

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

示例:

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

确保使用0dp作为宽度!

注意:如果您希望图标右对齐,则答案如下。哪个,我不确定你需要什么。

答案 4 :(得分:0)

你可以检查:

(中间:

 android:layout_toLeftOf="@+id/right"
        android:layout_toRightOf="@+id/left"

(右:android:layout_alignParentRight="true"

<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_centerInParent="true"
        android:layout_toLeftOf="@+id/right"
        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_alignParentRight="true"
       />
</RelativeLayout>

答案 5 :(得分:0)

经过一些拔毛,没有明显的溶解,我来到这个黑客。自定义textview类仅适用于textviews,我需要它来处理具有多个内容的布局。这个限制是你必须为正确的元素定义最大宽度。这确实让我想起了旧的html IE 6天..

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

        <FrameLayout
            android:id="@+id/resizing_element"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingRight="112dp" // Right padding to the amount of space you need for the right element
            android:background="@drawable/bg_chat_in" // Background drawable has the same transparant padding added to complete the illusion of this hack
            android:text="Long text content" />

        <FrameLayout
            android:id="@+id/meta_container"
            android:layout_width="112db" // This one has to have a predefined size.
            android:layout_height="wrap_content"
            android:layout_alignRight="@+id/content_container" // Align right places this element in the right padding of the first element>

        </FrameLayout>

    </RelativeLayout>

答案 6 :(得分:0)

您应该将第二个视图的android:layout_weight设置为小于1的值,以便它一直展开,直到最后一个视图到达布局的提示。

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="horizontal">

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

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="0.5"
        android:maxLines="1"
        android:ellipsize="end"/>

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

答案 7 :(得分:-1)

您可以参考this; 首先布置第一个左图标, 然后使用参考方法布局[文本视图和右图标];

绝对有效!

当然,根据您的要求,最后一个右侧图标可以设置为中间文本视图DrawableRight。但是这个方法有一个约束:右边的图标绑定限制到textview绑定。