亚马逊Android应用中分组可点击项UI元素的名称、组成及实现问题咨询
Hey Andrew, great question! That UI element you're referencing is a grouped list within a card container (often shorthanded as a "card with list items" in Material Design terminology). It’s a super common pattern for grouping related actionable options into a visually cohesive block—exactly how Amazon uses it for address management.
Official Name
In Material Design, this pattern falls under Grouped List Items in a Card Container. It’s a combination of two core Material components:
- The
Card(for the outer rounded, bordered container) List Items(for the individual clickable rows)
You might hear it called a "segmented card list" informally, but the official terminology ties it directly to Material’s List and Card component system.
Standard Composition Structure
This UI pattern has three essential parts:
- Outer Container: A rounded, bordered card (or container with a rounded background) that visually unifies all items. It provides consistent corner rounding and optional shadow for depth.
- Actionable List Items: Individual clickable/focusable rows, each including:
- Primary descriptive text (e.g., "Add new Address")
- Optional trailing icons (like the arrow you used for navigation)
- Built-in touch feedback (ripple effect) for interactivity
- Dividers: Thin horizontal lines between list items to separate options without breaking the card’s cohesive look.
Optimal Implementation (Aligned with Material Design)
Your final implementation works, but we can refine it to be more maintainable and aligned with official best practices:
Option 1: Use Pre-built Material Components (Recommended)
Leverage Material’s dedicated list components to handle styling, feedback, and dividers automatically:
<com.google.android.material.card.MaterialCardView android:layout_width="match_parent" android:layout_height="wrap_content" app:cardCornerRadius="8dp" app:strokeColor="@color/color_user_address_border" app:strokeWidth="1dp"> <com.google.android.material.list.MaterialListView android:layout_width="match_parent" android:layout_height="wrap_content" app:divider="@color/color_divider" app:dividerHeight="1dp"> <com.google.android.material.list.MaterialListItem android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true" android:focusable="true" app:listItemText="Add new Address" app:listItemEndIcon="@drawable/ic_arrow_big" app:listItemEndIconTint="@color/color_text_dark"/> <com.google.android.material.list.MaterialListItem android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true" android:focusable="true" app:listItemText="Shipping Addresses" app:listItemEndIcon="@drawable/ic_arrow_big" app:listItemEndIconTint="@color/color_text_dark"/> <com.google.android.material.list.MaterialListItem android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true" android:focusable="true" app:listItemText="Billing Addresses" app:listItemEndIcon="@drawable/ic_arrow_big" app:listItemEndIconTint="@color/color_text_dark"/> </com.google.android.material.list.MaterialListView> </com.google.android.material.card.MaterialCardView>
Option 2: Refined Custom Implementation (Like Your Final Version)
If you prefer sticking to basic views, streamline your code to avoid redundant constraints and leverage native Material components:
<com.google.android.material.card.MaterialCardView android:id="@+id/cvAddress" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="8dp" app:cardCornerRadius="8dp" app:strokeColor="@color/color_user_address_border" app:strokeWidth="1dp" app:layout_constraintEnd_toStartOf="@+id/margin_right" app:layout_constraintStart_toStartOf="@+id/margin_left" app:layout_constraintTop_toBottomOf="@+id/tvUserDataAddressHeadline"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/tvAddAddress" android:layout_width="match_parent" android:layout_height="50dp" android:background="?attr/selectableItemBackground" android:clickable="true" android:focusable="true" android:gravity="center_vertical" android:paddingHorizontal="16dp" android:text="Add new Address" android:textColor="@color/color_text_dark" android:textSize="16sp" app:drawableEndCompat="@drawable/ic_arrow_big" app:drawableTint="@color/color_text_dark"/> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/color_divider" android:layout_marginHorizontal="16dp"/> <TextView android:id="@+id/tvShippingAddress" android:layout_width="match_parent" android:layout_height="50dp" android:background="?attr/selectableItemBackground" android:clickable="true" android:focusable="true" android:gravity="center_vertical" android:paddingHorizontal="16dp" android:text="Shipping Addresses" android:textColor="@color/color_text_dark" android:textSize="16sp" app:drawableEndCompat="@drawable/ic_arrow_big" app:drawableTint="@color/color_text_dark"/> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/color_divider" android:layout_marginHorizontal="16dp"/> <TextView android:id="@+id/tvBillingAddress" android:layout_width="match_parent" android:layout_height="50dp" android:background="?attr/selectableItemBackground" android:clickable="true" android:focusable="true" android:gravity="center_vertical" android:paddingHorizontal="16dp" android:text="Billing Addresses" android:textColor="@color/color_text_dark" android:textSize="16sp" app:drawableEndCompat="@drawable/ic_arrow_big" app:drawableTint="@color/color_text_dark"/> </LinearLayout> </com.google.android.material.card.MaterialCardView>
Key improvements here:
- Replaced the outer
ConstraintLayoutwithMaterialCardViewto handle borders and rounding natively (no custom drawable needed) - Used
LinearLayoutfor inner rows to simplify the layout structure - Added horizontal margin to dividers for a more polished, professional look
- Used
android:paddingHorizontalinstead of separate start/end padding for cleaner code
Why Your Initial Nested Card Approach Had Issues
Nested MaterialCardView elements create duplicate border lines (since each card has its own stroke), which is why you saw overly thick borders. Using a single outer card with inner list items (or simple text views) eliminates this problem entirely.
内容的提问来源于stack exchange,提问作者Andrew

