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.
It's not one CardView
which hosts elements, it's several successive CardView
s 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"
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)
Separator
This one is just a LinearLayout
with TextView
and ImageView
inside:
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 TextView
s:
So the only question left, how do Google-guys "merge" cards into one big card and avoid extra shadows.
The trick is really simple:
CardView
's have card_view:cardCornerRadius="0dp"
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"
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"
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