What is the best practice to group items into CardView?

后端 未结 1 767
无人及你
无人及你 2020-12-12 18:11

CardView usually used to decorate exactly one element. But sometimes you need to wrap into this widget several items. Like in Inbox app, for example.

相关标签:
1条回答
  • 2020-12-12 19:01

    TL;DR:

    It's not one CardView which hosts elements, it's several successive CardViews with different margins:

    For the top CardView in group:

        android:layout_marginTop="5dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginBottom="0dp"
        card_view:cardCornerRadius="0dp"
    

    For the bottom CardView in group:

        android:layout_marginTop="0dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginBottom="5dp"
        card_view:cardCornerRadius="0dp"
    

    And the middle one, as set margins Top&Bottom to 0:

        android:layout_marginTop="0dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginBottom="0dp"
        card_view:cardCornerRadius="0dp"
    

    About Inbox app:

    This is hierarchy of the app (of course, simplified a bit):

    |android.support.v4.widget.DrawerLayout
    ---|FrameLayout
    -------|android.support.v7.widget.RecyclerView
    -------|android.support.v7.widget.Toolbar
    ---|android.support.design.widget.NavigationView

    The full structure even without navigation drawer & collapsed cards looks like:

    The interesting part starts, when you dive into the RecyclerView's items structure.
    There're 2 types of items Google uses - the separators (with date and actions on the right) and the cards. Even though cards have different content inside, from the ViewHolder perspective - RecyclerView has 2 types of items)

    1. Separator

      This one is just a LinearLayout with TextView and ImageView inside:

    2. Item Card

      Its layout adjusts based on the content being bind to the ViewHolder For example, simple email like the one in focus is a CardView with nested ImageView and 3 TextViews:

    So the only question left, how do Google-guys "merge" cards into one big card and avoid extra shadows.

    The trick is really simple:

    1. All CardView's have card_view:cardCornerRadius="0dp"
    2. Top CardView of the group have margin set 5dp for top/left/right, but 0dp for the bottom:

      android:layout_marginTop="5dp"
      android:layout_marginLeft="5dp"
      android:layout_marginRight="5dp"
      android:layout_marginBottom="0dp"
      
    3. Bottom CardView of the group have margin set 5dp for left/right/bottom, but 0dp for the top:

      android:layout_marginTop="0dp"
      android:layout_marginLeft="5dp"
      android:layout_marginRight="5dp"
      android:layout_marginBottom="5dp"
      
    4. Middle CardView of the group have margin set 5dp for left/right, but 0dp for the top/bottom:

      android:layout_marginTop="0dp"
      android:layout_marginLeft="5dp"
      android:layout_marginRight="5dp"
      android:layout_marginBottom="0dp"
      

    That's it!

    Here's a small example I've wrote:

    The layout (with tricky margins)

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="16dp"
        xmlns:card_view="http://schemas.android.com/apk/res-auto">
        <android.support.v7.widget.CardView
            android:layout_gravity="center"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="5dp"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp"
            android:layout_marginBottom="0dp"
            card_view:cardCornerRadius="0dp"
            card_view:contentPadding="10dp">
            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">
                <TextView
                    android:text="card1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textStyle="bold"/>
            </FrameLayout>
        </android.support.v7.widget.CardView>
        <android.support.v7.widget.CardView
            android:layout_gravity="center"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="0dp"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp"
            android:layout_marginBottom="0dp"
            card_view:cardCornerRadius="0dp"
            card_view:contentPadding="10dp">
            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">
                <TextView
                    android:text="card2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textStyle="bold"/>
            </FrameLayout>
        </android.support.v7.widget.CardView>
        <android.support.v7.widget.CardView
            android:layout_gravity="center"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="0dp"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp"
            android:layout_marginBottom="5dp"
            card_view:cardCornerRadius="0dp"
            card_view:contentPadding="10dp">
            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">
                <TextView
                    android:text="card3"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textStyle="bold"/>
            </FrameLayout>
        </android.support.v7.widget.CardView>
    </LinearLayout>
    

    I hope, it helps

    0 讨论(0)
提交回复
热议问题