如何创建多行、多列列表项布局?

How can I create a multiline, multicolumn list item layout?

我正在创建一个消息传递应用程序,目前正在处理收件箱。我正在使用 RecyclerView 来显示对话列表,并希望每个列表项看起来像这样:

  1. 最左边是 90dp x 90dp 的联系人图片
  2. 第一行有两列——联系人姓名和日期。日期应该 而不是 是我目前拥有的固定大小,但最多适合 DD/MM/YYYY (在 "Sunday" 之类的情况下可以更小)和应该锚定到右边距。联系人应根据需要进行扩展,以填写任何 space 截止日期。
  3. 第二行包含最后一条消息的所有文本。

我打算使用 layout_weight,但这在 RelativeLayout 中不起作用(并且不允许在较短的日期的情况下延长联系人姓名)和 LinearLayout 不允许我使用 layout_toEndOf。我是 Android 开发的新手,所以我不确定其中一个是否是 "right" 的答案。

完成我正在寻找的布局的正确方法是什么?

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">    

    <RelativeLayout
        android:id="@+id/conversation_info"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="@dimen/activity_horizontal_margin">

        <RelativeLayout
            android:id="@+id/conversation_image_layout"
            android:layout_width="90dp"
            android:layout_height="90dp">

            <ImageView
                android:id="@+id/conversation_contact_image"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent" />

        </RelativeLayout>    

        <TextView
            android:id="@+id/conversation_contact_name"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/activity_vertical_margin"
            android:gravity="center_vertical"
            android:textSize="@dimen/conversations_contact_font_size"
            android:layout_toEndOf="@id/conversation_image_layout" />    

        <TextView
            android:id="@+id/conversation_date"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_toEndOf="@id/conversation_contact_name"
            android:gravity="right"
            android:paddingRight="@dimen/activity_horizontal_margin"
            android:textSize="@dimen/conversations_date_font_size" />    

        <TextView
            android:id="@+id/conversation_snippet"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/conversation_contact_name"
            android:textSize="@dimen/conversations_snippet_font_size"
            android:layout_toRightOf="@id/conversation_image_layout" />

    </RelativeLayout>    

    </LinearLayout>

这是列表项当前的样子(我还没有加载联系人图片)。在大多数情况下都很好(尽管我的布局代码可能非常臃肿,所以如果有人能指出使它更简洁的方法,我将不胜感激)但请注意日期与联系人姓名和包装不在同一级别:

其中一个有问题的 textView 具有 MarginTop 属性,而另一个没有。要么在两者上都删除它,要么在两者上都添加它:

<TextView
        android:id="@+id/conversation_contact_name"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:gravity="center_vertical"
        android:textSize="@dimen/conversations_contact_font_size"
        android:layout_toEndOf="@id/conversation_image_layout" />    

    <TextView
        android:id="@+id/conversation_date"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_toEndOf="@id/conversation_contact_name"
        android:gravity="right"

        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:textSize="@dimen/conversations_date_font_size" />

此外,我建议您使用带有嵌套线性布局和权重的线性布局,以便在不同的屏幕和设备上获得更好的性能。如果您 运行 在不同的设备上使用它,这一切都可能会崩溃。不信,试试看:)

在我清楚一些布局参数并不符合我的想法后,我花了更多时间查看我的选择。

建议在列表项中嵌套LinearLayouts/uselayout_weight,因为添加的项越多,创建的视图数量也会迅速增加。我设法缩小我的代码并使用以下代码将其保存在单个 RelativeLayout 中:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/conversation_info"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="@dimen/activity_horizontal_margin">

    <ImageView
        android:id="@+id/conversation_contact_image"
        android:layout_width="64dp"
        android:layout_height="64dp"/>

    <TextView
        android:id="@+id/conversation_contact_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="@dimen/conversations_contact_font_size"
        android:layout_toEndOf="@id/conversation_contact_image"/>

    <TextView
        android:id="@+id/conversation_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignBaseline="@id/conversation_contact_name"
        android:textSize="@dimen/conversations_date_font_size"/>

    <TextView
        android:id="@+id/conversation_snippet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/conversation_contact_name"
        android:textSize="@dimen/conversations_snippet_font_size"
        android:layout_toEndOf="@id/conversation_contact_image"/>

</RelativeLayout>

显着变化:

  • 没有嵌套标签 - 没有必要在其自己的布局中对第一行进行分组
  • 使用 layout_alignBaseline - @Vucko 指出我在联系人姓名上使用了 marginTop 而不是日期。即使拆掉了,两人还是错位了。 android:gravity 没有效果,结果 none 实际上影响了布局中的文本
  • 已使用 layout_alignParentEnd 解决日期问题。我已经意识到,在我的例子中,布局组件通常只需要引用另一个,以便相对于布局的其余部分正确对齐。