android - personalizar - ¿Cuál es la mejor práctica para agrupar elementos en CardView?
cardview definicion (1)
TL; DR:
No es un CardView
que aloja elementos, sino varios CardView
con diferentes márgenes:
Para la parte superior de CardView
en el grupo:
android:layout_marginTop="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="0dp"
card_view:cardCornerRadius="0dp"
Para el CardView
inferior en el grupo:
android:layout_marginTop="0dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
card_view:cardCornerRadius="0dp"
Y el del medio, como establecer los márgenes Superior e Inferior a 0:
android:layout_marginTop="0dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="0dp"
card_view:cardCornerRadius="0dp"
Acerca de la aplicación Inbox:
Esta es la jerarquía de la aplicación (por supuesto, un poco simplificada):
| android.support.v4.widget.DrawerLayout
--- | FrameLayout
------- | android.support.v7.widget.RecyclerView
------- | android.support.v7.widget.Toolbar
--- | android.support.design.widget.NavigationView
La estructura completa, incluso sin el cajón de navegación y las tarjetas contraídas, se ve así:
La parte interesante comienza cuando te sumerges en la estructura de elementos de RecyclerView
.
Hay dos tipos de elementos que usa Google: los separadores (con fecha y acciones a la derecha) y las tarjetas. Aunque las tarjetas tienen contenido diferente dentro, desde la perspectiva de ViewHolder
, RecyclerView
tiene 2 tipos de elementos)
Este es solo un
LinearLayout
conTextView
eImageView
dentro:Su diseño se ajusta en función del contenido que se vincula al
ViewHolder
Por ejemplo, un simple correo electrónico como el que está en foco es unCardView
conImageView
anidado y 3TextView
s:
Entonces, la única pregunta que queda es cómo los chicos de Google "combinan" cartas en una carta grande y evitan las sombras adicionales.
El truco es realmente simple:
- Todos los
CardView
tienencard_view:cardCornerRadius="0dp"
Top
CardView
del grupo tiene margen establecido 5dp para arriba / izquierda / derecha, pero 0dp para la parte inferior:android:layout_marginTop="5dp" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_marginBottom="0dp"
El
CardView
inferior del grupo tiene un margen de 5dp para la izquierda / derecha / abajo, pero 0dp para la parte superior:android:layout_marginTop="0dp" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_marginBottom="5dp"
Middle
CardView
del grupo tiene un margen establecido de 5dp para la izquierda / derecha, pero 0dp para la parte superior / inferior:android:layout_marginTop="0dp" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_marginBottom="0dp"
¡Eso es!
Aquí hay un pequeño ejemplo que he escrito:
El diseño (con márgenes complicados)
<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>
Espero que ayude
CardView generalmente se utiliza para decorar exactamente un elemento. Pero a veces necesitas envolver en este widget varios elementos. Como en la aplicación Inbox, por ejemplo.
Entonces, ¿cuál es la mejor manera de hacer esto? Se puede implementar a través de LayoutManager personalizado o incluso de ItemDecoration personalizado. La implementación de LayoutManager personalizado no es una tarea fácil (con soporte completo de animaciones, decoraciones de elementos, etc.). En la segunda opción, el dibujo de los límites debe implementarse manualmente, ignorando la implementación de CardView (y Android-L elevation).