{"id":1976,"date":"2020-04-13T07:59:00","date_gmt":"2020-04-13T12:59:00","guid":{"rendered":"https:\/\/naps.com.mx\/blog\/?p=1976"},"modified":"2021-12-23T02:01:09","modified_gmt":"2021-12-23T08:01:09","slug":"menu-lateral-que-abre-un-cardview-en-android","status":"publish","type":"post","link":"https:\/\/naps.com.mx\/blog\/menu-lateral-que-abre-un-cardview-en-android\/","title":{"rendered":"Men\u00fa lateral que abre un CardView en Android"},"content":{"rendered":"<p>Aprenderemos a programar un men\u00fa lateral que abre un CardView en Android. Una vez que tenemos elaborado un men\u00fa lateral, de seguro queremos que al darle clic a alguna de sus opciones, nos realice alguna acci\u00f3n. En \u00e9ste art\u00edculo veremos c\u00f3mo mostrar un CardView utilizando el componente RecyclerView.<\/p>\n<p><!--more--><\/p>\n<blockquote><p><em><strong>\u00c9ste art\u00edculo est\u00e1 explicado en video:<a href=\"https:\/\/youtu.be\/PINqvwe8z54\" target=\"_blank\" rel=\"noopener\">\u00a0https:\/\/youtu.be\/PINqvwe8z54<\/a><\/strong><\/em><\/p><\/blockquote>\n<h2>Qu\u00e9 es un CardView<\/h2>\n<p>Un CardView nos permitir\u00e1 presentar informaci\u00f3n de una forma coherente y organizada (<a href=\"https:\/\/books.google.com.mx\/books?id=qkzrCQAAQBAJ&amp;lpg=PA603&amp;dq=cardview&amp;pg=PA603#v=onepage&amp;q=cardview&amp;f=false\" target=\"_blank\" rel=\"noopener\">Griffits, 2015<\/a>).<\/p>\n<div id=\"attachment_1981\" style=\"width: 361px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/Menu-lateral-que-abre-un-cardview-ejemplo.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1981\" class=\"wp-image-1981\" src=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/Menu-lateral-que-abre-un-cardview-ejemplo.png\" alt=\"Menu lateral que abre un cardview ejemplo\" width=\"351\" height=\"386\" srcset=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/Menu-lateral-que-abre-un-cardview-ejemplo.png 476w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/Menu-lateral-que-abre-un-cardview-ejemplo-273x300.png 273w\" sizes=\"auto, (max-width: 351px) 100vw, 351px\" \/><\/a><p id=\"caption-attachment-1981\" class=\"wp-caption-text\">Fig. 1. CardView que desarrollaremos<\/p><\/div>\n<p>En el ejemplo anterior, se tiene un art\u00edculo que forma parte de una lista de art\u00edculos, cada uno tiene un t\u00edtulo (\u00ab<em>\u00bfQu\u00e9 es el sobrepeso?\u00bb<\/em>), un subt\u00edtulo (\u00ab<em>Y en qu\u00e9 es diferente de la obesidad\u00bb<\/em>), una imagen, la leyenda Saber m\u00e1s junto con un icono de flecha hacia abajo, y un bot\u00f3n que abre un men\u00fa contextual.<\/p>\n<h2>Qu\u00e9 es un RecyclerView<\/h2>\n<p>RecyclerView es una de las vistas m\u00e1s com\u00fanmente usadas en Android. Viene siendo una versi\u00f3n m\u00e1s avanzada de ListView. Es un contenedor que permite administrar un conjunto grande de datos o informaci\u00f3n, al reciclarlos eficientemente a medida que la lista es desplazada hacia arriba o hacia abajo (<a href=\"https:\/\/books.google.com.mx\/books?id=-6HBDwAAQBAJ&amp;lpg=PA1&amp;dq=recyclerview&amp;pg=PT120#v=onepage&amp;q=recyclerview&amp;f=false\" target=\"_blank\" rel=\"noopener\">Guleria, 2019<\/a>).<\/p>\n<h2>Pasos para programar un men\u00fa lateral que abre un CardView<\/h2>\n<p>En los siguientes pasos, considero que ya tienes desarrollado un Men\u00fa Lateral. En caso de que no fuese as\u00ed, te invito a realizarlo siguiendo los pasos que se muestran en el siguiente enlace:\u00a0<a href=\"https:\/\/naps.com.mx\/blog\/pasos-para-desarrollar-un-menu-en-una-app-android\/\">Pasos para desarrollar un men\u00fa en una app Android.<\/a><\/p>\n<p>Veamos ahora los pasos para programar el men\u00fa lateral que abre un CardView<\/p>\n<h2>Paso 1. A\u00f1adir las dependencias que utilizaremos<\/h2>\n<p>Abre tu archivo build.gradle (Module:app) y en la secci\u00f3n dependencies a\u00f1ade las siguientes:<\/p>\n<pre class=\"\">implementation 'com.android.support:cardview-v7:27.1.1'\r\nimplementation 'com.android.support:recyclerview-v7:27.1.1'\r\nimplementation 'com.squareup.picasso:picasso:2.5.2'<\/pre>\n<h2>Paso 2. Crea el modelo de datos que deseas mostrar usando CardView<\/h2>\n<p>El modelo de datos es una nueva clase Java.\u00a0Ubica el paquete donde crear\u00e1s \u00e9sta clase. Puede ser tu com o un package dentro de tu com. Por ejemplo:<\/p>\n<p><a href=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/Captura-de-Pantalla-2020-04-02-a-las-22.50.28.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1979\" src=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/Captura-de-Pantalla-2020-04-02-a-las-22.50.28.png\" alt=\"Menu lateral que abre un cardview\" width=\"522\" height=\"378\" srcset=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/Captura-de-Pantalla-2020-04-02-a-las-22.50.28.png 522w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/Captura-de-Pantalla-2020-04-02-a-las-22.50.28-300x217.png 300w\" sizes=\"auto, (max-width: 522px) 100vw, 522px\" \/><\/a><\/p>\n<p>En la imagen de arriba, la clase que creamos se llama Dato y est\u00e1 dentro de un package llamdo Models. (Pero puede estar en el <em>com.naps.aaa.bbb<\/em>).\u00a0Los packages Activities, Adapter, Clases y Fragments los he creado para organizar mejor la aplicaci\u00f3n.<\/p>\n<p>Da clic derecho y selecciona New-&gt;Java Class.<\/p>\n<p><a href=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-modelo-datos.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1983\" src=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-modelo-datos.png\" alt=\"menu lateral que abre un cardview modelo datos\" width=\"1048\" height=\"834\" srcset=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-modelo-datos.png 1048w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-modelo-datos-300x239.png 300w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-modelo-datos-768x611.png 768w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-modelo-datos-1024x815.png 1024w\" sizes=\"auto, (max-width: 1048px) 100vw, 1048px\" \/><\/a><\/p>\n<p>El c\u00f3digo de la clase Dato.java es el siguiente:<\/p>\n<pre class=\"lang:java decode:true \">public class Dato {\r\n    private String titulo;\r\n    private String subtitulo;\r\n    private int imagen;\r\n    private String contenido;\r\n\r\n    \/\/ Constructor de la clase\r\n    public Dato(String titulo, String subtitulo, int imagen, String contenido) {\r\n        this.titulo = titulo;\r\n        this.subtitulo = subtitulo;\r\n        this.imagen = imagen;\r\n        this.contenido = contenido;\r\n    }\r\n\r\n    \/\/ Metodos setter y getter\r\n    public String getSubtitulo() {\r\n        return subtitulo;\r\n    }\r\n\r\n    public void setSubtitulo(String subtitulo) {\r\n        this.subtitulo = subtitulo;\r\n    }\r\n\r\n    public String getTitulo() {\r\n        return titulo;\r\n    }\r\n\r\n    public void setTitulo(String titulo) {\r\n        this.titulo = titulo;\r\n    }\r\n\r\n    public void setContenido(String contenido){\r\n        this.contenido = contenido;\r\n    };\r\n\r\n    public int getImagen() {\r\n        return imagen;\r\n    }\r\n\r\n    public String getContenido() {\r\n        return contenido;\r\n    }\r\n\r\n    public void setImagen(int imagen) {\r\n        this.imagen = imagen;\r\n    }\r\n\r\n}<\/pre>\n<h2>Paso 3. Crea el fragment donde aparecer\u00e1 el CardView<\/h2>\n<p>Clic derecho sobre el package donde vas a crear el fragment luego en New-&gt;Fragment-&gt;Fragment (Blank)<\/p>\n<p><a href=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-crear-fragment.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1986\" src=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-crear-fragment.png\" alt=\"menu lateral que abre un cardview crear fragment\" width=\"1590\" height=\"1324\" srcset=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-crear-fragment.png 1590w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-crear-fragment-300x250.png 300w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-crear-fragment-768x640.png 768w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-crear-fragment-1024x853.png 1024w\" sizes=\"auto, (max-width: 1590px) 100vw, 1590px\" \/><\/a><\/p>\n<h2>Paso 4. Modificar el layout fragment_informacion.xml<\/h2>\n<p>Abre el archivo fragment_informacion.xml que se encuentra dentro de res-&gt;layout<\/p>\n<p>En \u00e9ste archivo agregaremos un componente RecyclerView. El archivo quedar\u00e1 m\u00e1s o menos de la siguiente forma (considera que la linea que indica el context cambiar\u00e1 en tu proyecto):<\/p>\n<pre class=\"lang:xhtml mark:8-12 decode:true \">&lt;FrameLayout \r\n    xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\r\n    xmlns:tools=\"http:\/\/schemas.android.com\/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    tools:context=\"com.naps.gibgarcia.npsalud.Fragments.InformacionFragment\"&gt;\r\n\r\n    &lt;android.support.v7.widget.RecyclerView\r\n        android:id=\"@+id\/recyclerView\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:scrollbars=\"vertical\"\/&gt;\r\n\r\n&lt;\/FrameLayout&gt;<\/pre>\n<p>Deber\u00e1s agregar las l\u00edneas del componente RecyclerView \u00fanicamente.<\/p>\n<h2>Paso 5. Crear un layout para los item de informaci\u00f3n<\/h2>\n<p>Dentro del RecyclerView ir\u00e1n los item de informaci\u00f3n con el dise\u00f1o que mostramos arriba, en la Fig. 1.<\/p>\n<p>Vamos a dise\u00f1ar ese layout.<\/p>\n<p>En res-&gt;layout, da clic derecho, luego en New-&gt;Layout resource file<\/p>\n<p>Como nombre de archivo, usar\u00e9 list_item_informacion.xml<\/p>\n<p><a href=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-item.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1988\" src=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-item.png\" alt=\"menu lateral que abre un cardview item\" width=\"1354\" height=\"504\" srcset=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-item.png 1354w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-item-300x112.png 300w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-item-768x286.png 768w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-item-1024x381.png 1024w\" sizes=\"auto, (max-width: 1354px) 100vw, 1354px\" \/><\/a><\/p>\n<p>A continuaci\u00f3n te muestro c\u00f3mo qued\u00f3 el c\u00f3digo que utilic\u00e9.<\/p>\n<p>Se crea un componente CardView. Dentro, va un LinearLayout vertical. \u00c9ste LinearLayout tiene tres elementos: un Toolbar (que contiene el t\u00edtulo y el subt\u00edtulo), un ImageView (para la imagen), otro LinearLayout (\u00e9sta vez horizontal), que contiene un TextView (que lleva la frase \u00abSaber m\u00e1s\u00bb), y un ImageView (con una flecha hacia abajo). Notar\u00e1s otro LinearLayout, y es el que contiene la informaci\u00f3n que aparecer\u00e1 cuando se le de clic a la flecha hacia abajo para \u00absaber m\u00e1s\u00bb.<\/p>\n<pre class=\"lang:java decode:true \">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\r\n&lt;android.support.v7.widget.CardView\r\n    xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    xmlns:app=\"http:\/\/schemas.android.com\/apk\/res-auto\"\r\n    xmlns:tools=\"http:\/\/schemas.android.com\/tools\"\r\n    android:id=\"@+id\/cardView\"\r\n    android:layout_margin=\"16dp\"\r\n    app:cardUseCompatPadding=\"true\"\r\n    app:cardCornerRadius=\"4dp\"\r\n    tools:context=\"com.naps.gibgarcia.npsalud.Fragments.InformacionFragment\"&gt;\r\n\r\n&lt;!--  app:cardBackgroundColor=\"#E2E2E2\"  --&gt;\r\n\r\n    &lt;LinearLayout\r\n        android:id=\"@+id\/linearLayoutCardContent\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:orientation=\"vertical\"&gt;\r\n\r\n        &lt;android.support.v7.widget.Toolbar\r\n            android:id=\"@+id\/toolbarCard\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:background=\"@android:color\/white\"\r\n            app:popupTheme=\"@style\/Theme.AppCompat.Light\"\r\n            app:subtitleTextAppearance=\"@style\/Card.Subtitle\"\r\n            app:theme=\"@style\/ToolbarCard\"\r\n            app:titleTextAppearance=\"@style\/Card.Title\" \/&gt;\r\n\r\n        &lt;ImageView\r\n            android:id=\"@+id\/imageViewPoster\"\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_marginTop=\"8dp\"\r\n            android:adjustViewBounds=\"true\"\r\n            android:contentDescription=\"contentDescription\"\r\n            android:src=\"@drawable\/blur\" \/&gt;\r\n\r\n        &lt;LinearLayout\r\n\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:id=\"@+id\/unlinearl\"\r\n            android:orientation=\"horizontal\"\r\n            android:padding=\"8dp\"&gt;\r\n\r\n            &lt;TextView\r\n                android:layout_width=\"0dp\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_gravity=\"center_vertical\"\r\n                android:layout_weight=\"1\"\r\n                android:gravity=\"center_vertical\"\r\n                android:text=\"Saber m\u00e1s\"\r\n                android:textColor=\"@android:color\/black\"\r\n                android:textSize=\"20sp\" \/&gt;\r\n\r\n            &lt;ImageView\r\n                android:id=\"@+id\/imageViewExpand\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:background=\"@android:color\/transparent\"\r\n                android:contentDescription=\"Details\"\r\n                android:src=\"@drawable\/more\" \/&gt;\r\n        &lt;\/LinearLayout&gt;\r\n\r\n\r\n        &lt;LinearLayout\r\n            android:id=\"@+id\/linearLayoutDetails\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:orientation=\"vertical\"\r\n            android:paddingLeft=\"8dp\"\r\n            android:visibility=\"gone\"&gt;\r\n\r\n            &lt;TextView\r\n                android:id=\"@+id\/textViewInfo\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:text=\"Infoo\"\r\n                android:textColor=\"@android:color\/black\"\r\n                android:textSize=\"16sp\" \/&gt;\r\n        &lt;\/LinearLayout&gt;\r\n\r\n\r\n    &lt;\/LinearLayout&gt;\r\n\r\n\r\n\r\n&lt;\/android.support.v7.widget.CardView&gt;<\/pre>\n<p>Notas que utiliza algunos estilos que a\u00fan no est\u00e1n establecidos. Vamos a crearlos en el archivo res-&gt;values-&gt;styles.xml<\/p>\n<pre class=\"lang:xhtml decode:true \">&lt;resources&gt;\r\n    &lt;!-- Base application theme. --&gt;\r\n    &lt;style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\"&gt;\r\n        &lt;!-- Customize your theme here. --&gt;\r\n        &lt;item name=\"colorPrimary\"&gt;@color\/colorPrimary&lt;\/item&gt;\r\n        &lt;item name=\"colorPrimaryDark\"&gt;@color\/colorPrimaryDark&lt;\/item&gt;\r\n        &lt;item name=\"colorAccent\"&gt;@color\/colorAccent&lt;\/item&gt;\r\n    &lt;\/style&gt;\r\n    &lt;style name=\"ToolbarCard\" \r\n        parent=\"ThemeOverlay.AppCompat.ActionBar\"&gt;\r\n        &lt;item name=\"colorPrimary\"&gt;@android:color\/black&lt;\/item&gt;\r\n        &lt;item name=\"android:textColorPrimary\"&gt;@android:color\/black&lt;\/item&gt;\r\n    &lt;\/style&gt;\r\n    &lt;style name=\"Card.Title\" \r\n        parent=\"TextAppearance.Widget.AppCompat.Toolbar.Title\"&gt;\r\n        &lt;item name=\"android:textSize\"&gt;24sp&lt;\/item&gt;\r\n    &lt;\/style&gt;\r\n    &lt;style name=\"Card.Subtitle\" \r\n        parent=\"TextAppearance.Widget.AppCompat.Toolbar.Subtitle\"&gt;\r\n        &lt;item name=\"android:textSize\"&gt;16sp&lt;\/item&gt;\r\n        &lt;item name=\"android:textColor\"&gt;@android:color\/darker_gray&lt;\/item&gt;\r\n    &lt;\/style&gt;\r\n&lt;\/resources&gt;<\/pre>\n<p>T\u00fa solo agrega las l\u00edneas correspondientes a los 3 estilos ToolbarCard, Title y Subtitle.<\/p>\n<h2>Paso 6. Crear un Adapter para el RecyclerView<\/h2>\n<p>Se necesita un adapter que realice un enlace entre los datos que deseamos mostrar, y \u00a0la vista que los desplegar\u00e1 en pantalla, en \u00e9ste caso un RecyclerView.<\/p>\n<p>Damos clic derecho sobre el package donde lo crearemos, luego en New-&gt;Java Class, y como nombre, usar\u00e9 InformacionAdapter.<\/p>\n<pre class=\"lang:java decode:true\">\/\/ Hereda de RecyclerView.Adapter\r\npublic class InformacionAdapter extends RecyclerView.Adapter&lt;InformacionAdapter.ViewHolder&gt; {\r\n    \/\/ Una lista de objetos \"Dato\"\r\n    private List&lt;Dato&gt; datos;\r\n    \/\/ id del layout list_item_informacion\r\n    private int layout;\r\n    private OnItemClickListener itemClickListener;\r\n    private Context context;\r\n    private static final int DURATION = 250;    \r\n    \r\n    public InformacionAdapter(List&lt;Dato&gt; datos, int layout, OnItemClickListener listener) {\r\n            this.datos = datos;\r\n            this.layout = layout;\r\n            this.itemClickListener = listener;\r\n            }\r\n    \r\n    @Override\r\n    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {\r\n            View v = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);\r\n            context = parent.getContext();\r\n            ViewHolder vh = new ViewHolder(v);\r\n            return vh;\r\n            }\r\n    \r\n    @Override\r\n    public void onBindViewHolder( ViewHolder holder, int position) {\r\n            holder.bind(datos.get(position), itemClickListener);\r\n            }\r\n    \r\n    @Override\r\n    public int getItemCount() {\r\n            return datos.size();\r\n            }\r\n    \r\n    public  class ViewHolder extends  RecyclerView.ViewHolder{\r\n        \/\/ Elementos de dise\u00f1o de list_item_informacion.xml\r\n        public ImageView imageViewPoster;\r\n        public ViewGroup linearLayoutDetails;\r\n        public Toolbar toolbarCard;\r\n        public LinearLayout unlinearl;\r\n        public ImageView imageViewExpand;\r\n        public TextView textViewInfo;\r\n    \r\n        public ViewHolder(View itemView){\r\n            super(itemView);\r\n            \/\/ Enlazamos los elementos de la vista\r\n            imageViewPoster = itemView.findViewById(R.id.imageViewPoster);\r\n            linearLayoutDetails =  itemView.findViewById(R.id.linearLayoutDetails);\r\n            toolbarCard =  itemView.findViewById(R.id.toolbarCard);\r\n            unlinearl =  itemView.findViewById(R.id.unlinearl);\r\n            imageViewExpand =  itemView.findViewById(R.id.imageViewExpand);\r\n            textViewInfo =  itemView.findViewById(R.id.textViewInfo);\r\n        }\r\n    \r\n    \r\n        public void bind(final Dato dato, final OnItemClickListener listener){\r\n            \/\/ Sustituimos los elementos por su valor dentro de la lista de datos\r\n            toolbarCard.setTitle(dato.getTitulo());\r\n            toolbarCard.setSubtitle(dato.getSubtitulo());\r\n            \/\/ Cree un menu dentro de res-&gt;layout-&gt;menu con el nombre card_menu\r\n            toolbarCard.inflateMenu(R.menu.card_menu);\r\n            toolbarCard.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {\r\n                @Override\r\n                public boolean onMenuItemClick(MenuItem item) {\r\n                    switch (item.getItemId()) {\r\n                        case R.id.action_option1:\r\n                            Toast.makeText(context, \"op1\", Toast.LENGTH_SHORT).show();\r\n                            break;\r\n                        case R.id.action_option2:\r\n                            Toast.makeText(context, \"op2\", Toast.LENGTH_SHORT).show();\r\n                            break;\r\n                        case R.id.action_option3:\r\n                            Toast.makeText(context, \"op3\", Toast.LENGTH_SHORT).show();\r\n                            break;\r\n                    }\r\n                    return true;\r\n                }\r\n            });\r\n            textViewInfo.setText(dato.getContenido());\r\n            \/\/ Mostrar y ocultar la informaci\u00f3n\r\n            unlinearl.setOnClickListener(new View.OnClickListener() {\r\n                @Override\r\n                public void onClick(View view) {\r\n                    if (linearLayoutDetails.getVisibility() == View.GONE) {\r\n                        \/\/ Cree la clase ExpandAndCollpaseViewUtil\r\n                        ExpandAndCollapseViewUtil.expand(linearLayoutDetails, DURATION);\r\n                        imageViewExpand.setImageResource(R.drawable.more);\r\n                        \/\/ Rotamos el icono de flecha 180 grados\r\n                        Animation animation = new RotateAnimation(0.0f, -180.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);\r\n                        animation.setFillAfter(true);\r\n                        animation.setDuration(DURATION);\r\n                        imageViewExpand.startAnimation(animation);\r\n    \r\n                    } else {\r\n                        ExpandAndCollapseViewUtil.collapse(linearLayoutDetails, DURATION);\r\n                        imageViewExpand.setImageResource(R.drawable.less);\r\n                        Animation animation = new RotateAnimation(0.0f, 180.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);\r\n                        animation.setFillAfter(true);\r\n                        animation.setDuration(DURATION);\r\n                        imageViewExpand.startAnimation(animation);\r\n    \r\n                    }\r\n                }\r\n            });\r\n    \r\n    \r\n            \/\/ Picasso mejora el uso de imagenes\r\n            \/\/ square.github.io\/picasso\r\n    \r\n            Picasso.with(context).load(dato.getImagen())\r\n                        .into(imageViewPoster);\r\n    \r\n            itemView.setOnClickListener(new View.OnClickListener() {\r\n                @Override\r\n                public void onClick(View view) {\r\n                    listener.onItemClick(dato, getAdapterPosition());\r\n                }\r\n            });\r\n        }\r\n    }\r\n    \r\n    \r\n    public interface OnItemClickListener{\r\n        void onItemClick(Dato dato, int position);\r\n    }\r\n}<\/pre>\n<h2>Paso 7. Crear el menu de cada tarjeta<\/h2>\n<p>Deseamos que cada tarjeta contenga un men\u00fa similar a \u00e9ste:<\/p>\n<p><a href=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-card_menu.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1995\" src=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-card_menu.png\" alt=\"menu lateral que abre un cardview card_menu\" width=\"350\" height=\"385\" srcset=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-card_menu.png 476w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-card_menu-273x300.png 273w\" sizes=\"auto, (max-width: 350px) 100vw, 350px\" \/><\/a><\/p>\n<p>En el c\u00f3digo de adapter hay una l\u00ednea que manda a llamar ese men\u00fa:<\/p>\n<p>toolbarCard.inflateMenu(R.menu.card_menu);<\/p>\n<p>Pero hay que crear ese men\u00fa. Ya hay un directorio de men\u00fa que creamos en el art\u00edculo anterior. Est\u00e1 en res-&gt;layout-&gt;menu<\/p>\n<p>De clic derecho sobre el directorio menu, luego en New-&gt;Menu Resource File<\/p>\n<p>Cree un nuevo archivo con el nombre: card_menu.xml<\/p>\n<p><a href=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-creando-card_menu.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1996\" src=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-creando-card_menu.png\" alt=\"menu lateral que abre un cardview creando card_menu\" width=\"988\" height=\"462\" srcset=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-creando-card_menu.png 988w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-creando-card_menu-300x140.png 300w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-creando-card_menu-768x359.png 768w\" sizes=\"auto, (max-width: 988px) 100vw, 988px\" \/><\/a><\/p>\n<p>El c\u00f3digo de \u00e9ste archivo ser\u00e1 similar a \u00e9ste:<\/p>\n<pre class=\"lang:xhtml decode:true \">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\r\n&lt;menu xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\r\n    xmlns:app=\"http:\/\/schemas.android.com\/apk\/res-auto\"\r\n    xmlns:tools=\"http:\/\/schemas.android.com\/tools\"\r\n    tools:context=\".MainActivity\"&gt;\r\n\r\n    &lt;item\r\n        android:id=\"@+id\/action_option1\"\r\n        android:title=\"Compartir\"\r\n        app:showAsAction=\"never\" \/&gt;\r\n\r\n    &lt;item\r\n        android:id=\"@+id\/action_option2\"\r\n        android:title=\"Enviar a mi correo\"\r\n        app:showAsAction=\"never\" \/&gt;\r\n\r\n    &lt;item\r\n        android:id=\"@+id\/action_option3\"\r\n        android:title=\"Archivar\"\r\n        app:showAsAction=\"never\" \/&gt;\r\n&lt;\/menu&gt;<\/pre>\n<p>Observas que contiene las tres opciones de la ilustraci\u00f3n, con sus id correspondientes.<\/p>\n<h2>Paso 8. Crear una clase para el efecto Expandir y Colapsar<\/h2>\n<p>Al dar clic al icono a la derecha de \u00absaber m\u00e1s\u00bb, se expande la tarjeta, mostrando informaci\u00f3n. El icono rota y se muestra como una flecha hacia arriba, y al dar clic sobre \u00e9sta, la tarjeta se colapsa, ocultando la informaci\u00f3n.<\/p>\n<p>Para realizar \u00e9ste efecto crearemos una clase llamada ExpandAndCollapseViewUtil.<\/p>\n<p>De clic derecho sobre el package donde va a crear la clase. Luego en New-&gt;Java Class.<\/p>\n<p><a href=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-expand-and-collapse.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1998\" src=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-expand-and-collapse.png\" alt=\"menu lateral que abre un cardview expand and collapse\" width=\"1048\" height=\"834\" srcset=\"https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-expand-and-collapse.png 1048w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-expand-and-collapse-300x239.png 300w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-expand-and-collapse-768x611.png 768w, https:\/\/naps.com.mx\/blog\/wp-content\/uploads\/2020\/04\/menu-lateral-que-abre-un-cardview-expand-and-collapse-1024x815.png 1024w\" sizes=\"auto, (max-width: 1048px) 100vw, 1048px\" \/><\/a><\/p>\n<p>El c\u00f3digo de \u00e9sta clase es el siguiente:<\/p>\n<pre class=\"lang:java decode:true\">public class ExpandAndCollapseViewUtil {\r\n    public static void expand(final ViewGroup v, int duration) {\r\n        slide(v, duration, true);\r\n    }\r\n\r\n    public static void collapse(final ViewGroup v, int duration) {\r\n        slide(v, duration, false);\r\n    }\r\n\r\n    private static void slide(final ViewGroup v, int duration, final boolean expand) {\r\n        try {\r\n            \/\/onmeasure method is protected\r\n            Method m = v.getClass().getDeclaredMethod(\"onMeasure\", int.class, int.class);\r\n            m.setAccessible(true);\r\n            m.invoke(\r\n                    v,\r\n                    View.MeasureSpec.makeMeasureSpec(((View) v.getParent()).getMeasuredWidth(), View.MeasureSpec.AT_MOST),\r\n                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)\r\n            );\r\n        } catch (Exception e) {\r\n            Log.e(\"slideAnimation\", e.getMessage(), e);\r\n        }\r\n\r\n        final int initialHeight = v.getMeasuredHeight();\r\n\r\n        if (expand) {\r\n            v.getLayoutParams().height = 0;\r\n        } else {\r\n            v.getLayoutParams().height = initialHeight;\r\n        }\r\n        v.setVisibility(View.VISIBLE);\r\n\r\n        Animation a = new Animation() {\r\n            @Override\r\n            protected void applyTransformation(float interpolatedTime, Transformation t) {\r\n                int newHeight = 0;\r\n                if (expand) {\r\n                    newHeight = (int) (initialHeight * interpolatedTime);\r\n                } else {\r\n                    newHeight = (int) (initialHeight * (1 - interpolatedTime));\r\n                }\r\n                v.getLayoutParams().height = newHeight;\r\n                v.requestLayout();\r\n\r\n                if (interpolatedTime == 1 &amp;&amp; !expand) {\r\n                    v.setVisibility(View.GONE);\r\n                }\r\n            }\r\n\r\n            @Override\r\n            public boolean willChangeBounds() {\r\n                return true;\r\n            }\r\n        };\r\n\r\n        a.setDuration(duration);\r\n        v.startAnimation(a);\r\n    }\r\n\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h2>Paso 9. Enlazar todo: c\u00f3digo del InformacionFragment<\/h2>\n<p>Vamos al archivo InformacionFragment, que es el fragment que contendr\u00e1 nuestros CardView. Recuerda que el layout de \u00e9ste fragment, ya contiene un RecyclerView.<\/p>\n<p>En el m\u00e9todo onCreate, enlazamos todo.<\/p>\n<p>En el m\u00e9todo getAllData (es un m\u00e9todo propio), se crea un ArrayList de objetos de clase \u00abDato\u00bb, con algunos valores de ejemplo. \u00c9sta lista es pasada al adapter que creamos, junto con el layout de los items.<\/p>\n<p>El c\u00f3digo ser\u00e1 como el siguiente:<\/p>\n<pre class=\"lang:java decode:true \">public class InformacionFragment extends Fragment {\r\n    private List&lt;Dato&gt; datos;\r\n    private RecyclerView.Adapter mAdapter;\r\n    private RecyclerView.LayoutManager mLayoutManager;\r\n    private RecyclerView mRecyclerView;\r\n\r\n    public InformacionFragment() {\r\n        \/\/ Required empty public constructor\r\n    }\r\n\r\n    @Override\r\n    public View onCreateView(LayoutInflater inflater, ViewGroup container,\r\n                             Bundle savedInstanceState) {\r\n        \/\/ Inflate the layout for this fragment\r\n        View view = inflater.inflate(R.layout.fragment_informacion, container, false);\r\n        datos = this.getAllData();\r\n        mRecyclerView =  view.findViewById(R.id.recyclerView);\r\n        mLayoutManager = new LinearLayoutManager(getContext());\r\n        mAdapter = new InformacionAdapter(datos, R.layout.list_item_informacion,\r\n                new InformacionAdapter.OnItemClickListener() {\r\n                    @Override\r\n                    public void onItemClick(Dato dato, int position) {\r\n\r\n\r\n                    }\r\n                });\r\n        mRecyclerView.setHasFixedSize(true);\r\n        \/\/ A\u00f1ade un efecto por defecto, si le pasamos null lo desactivamos por completo\r\n        mRecyclerView.setItemAnimator(new DefaultItemAnimator());\r\n\r\n        \/\/ Enlazamos el layout manager y adaptador directamente al recycler view\r\n        mRecyclerView.setLayoutManager(mLayoutManager);\r\n        mRecyclerView.setAdapter(mAdapter);\r\n\r\n\r\n        return view;\r\n    }\r\n\r\n    private List&lt;Dato&gt; getAllData(){\r\n        return new ArrayList&lt;Dato&gt;() {{\r\n            add(new Dato(\"\u00bfQu\u00e9 es el sobrepeso?\",\"Y en qu\u00e9 es diferente de la obesidad\",  R.drawable.obesity, \"La obesidad se define como un aumento de composici\u00f3n de grasa corporal. Este aumento se traduce en un incremento del peso y aunque no todo incremento del peso corporal es debido a un aumento del tejido adiposo, en la pr\u00e1ctica m\u00e9dica el concepto de obesidad est\u00e1 relacionado con el peso corporal. La obesidad debe ser entendida como una enfermedad cr\u00f3nica, de forma semejante que lo es la diabetes mellitus o la hipertensi\u00f3n arterial. (Fuente: Infosalus.com)\\n\" +\r\n                    \"\\n \"));\r\n            add(new Dato(\"\u00bfQu\u00e9 es el IMC?\", \"Por qu\u00e9 es importante saberlo\",R.drawable.imc, \"\"));\r\n            add(new Dato(\"\u00bfC\u00f3mo medir la cintura?\", \"C\u00f3mo saber si tienes la medida correcta\",R.drawable.belly, \"\"));\r\n            add(new Dato(\"Alimentos que acumulan grasa abdominal\", \"Y que debes evitar\",R.drawable.food, \"\"));\r\n\r\n\r\n        }};\r\n    }\r\n\r\n}<\/pre>\n<h2>Paso 10. Hacer que la opci\u00f3n del men\u00fa lateral abra el fragment que hemos creado<\/h2>\n<p>Vamos al MainActivity. (Recuerda que en el art\u00edculo\u00a0<a href=\"https:\/\/naps.com.mx\/blog\/pasos-para-desarrollar-un-menu-en-una-app-android\/\">Pasos para desarrollar un men\u00fa en una app Android<\/a>\u00a0creamos un men\u00fa con una opci\u00f3n que se llama Informaci\u00f3n. \u00c9sta es la opci\u00f3n que usaremos para abrir nuestro fragment que contiene el RecyclerView con CardView).<\/p>\n<p>Busca la l\u00ednea que enlaza a navigationView. Se ve as\u00ed:<\/p>\n<p><span class=\"crayon-v\">navigationView<\/span> <span class=\"crayon-o\">=<\/span> <span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">NavigationView<\/span><span class=\"crayon-sy\">)\u00a0<\/span><span class=\"crayon-e\">findViewById<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">R<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-v\">id<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-v\">navview<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">;<\/span><\/p>\n<p>Debajo de esa l\u00ednea escribiremos el c\u00f3digo que detectar\u00e1 cuando se da un clic a una opci\u00f3n del men\u00fa. Es \u00e9ste:<\/p>\n<pre class=\"lang:java decode:true\">        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {\r\n            @Override\r\n            public boolean onNavigationItemSelected(@NonNull MenuItem item) {\r\n\r\n                boolean fragmentTransaction = false;\r\n\r\n                switch (item.getItemId()){\r\n                    \r\n                    case R.id.menu_informacion:\r\n                        frg = new InformacionFragment();\r\n                        changeFragment(frg, item);\r\n                        drawerLayout.closeDrawers();\r\n                        fragmentTransaction = false;\r\n                        break;\r\n                }\r\n\r\n                if (fragmentTransaction){\r\n                    changeFragment (fragment , item );\r\n                    drawerLayout.closeDrawers();\r\n                }\r\n                return true;\r\n            }<\/pre>\n<p>Si ya hab\u00edas creado \u00e9ste Listener, no debes crear otro, sino \u00fanicamente a\u00f1adir el caso correspondiente:<\/p>\n<p>case R.id.menu_informacion:<\/p>\n<p>frg = new InformacionFragment();<\/p>\n<p>changeFragment(frg, item);<\/p>\n<p>drawerLayout.closeDrawers();<\/p>\n<p>fragmentTransaction = false;<\/p>\n<p>break;<\/p>\n<p>Notas que utiliza una funci\u00f3n propia llamada changeFragment. \u00c9sta funci\u00f3n va una vez cierres la llave del onCreate, y contiene el siguiente c\u00f3digo:<\/p>\n<pre class=\"lang:java decode:true \">    private void changeFragment( Fragment fragment, MenuItem item){\r\n        getSupportFragmentManager()\r\n                .beginTransaction()\r\n                .replace(R.id.content_frame, fragment)\r\n                .commit();\r\n        item.setChecked(true);\r\n        getSupportActionBar().setTitle(item.getTitle());\r\n    }<\/pre>\n<p>\u00a1Listo! Al darle clic a la opci\u00f3n Informaci\u00f3n del Men\u00fa Lateral, se abre un fragment que contiene un RecyclerView, con una lista de CardView. Espero logres completar tu proyecto en programar un men\u00fa lateral que abre un CardView en Android.<\/p>\n<p>Mira el resultado y los pasos ya descritos en video:<br \/>\n<iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/PINqvwe8z54\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Aprenderemos a programar un men\u00fa lateral que abre un CardView en Android. Una vez que tenemos elaborado un men\u00fa lateral, de seguro queremos que al darle clic a alguna de sus opciones, nos realice alguna acci\u00f3n. En \u00e9ste art\u00edculo veremos c\u00f3mo mostrar un CardView utilizando el componente RecyclerView.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"amp_status":"","footnotes":""},"categories":[234],"tags":[275,235,273,274],"class_list":["post-1976","post","type-post","status-publish","format-standard","hentry","category-aplicaciones-moviles","tag-cardview","tag-desarrollo-de-aplicaciones-moviles","tag-menu-lateral-en-android","tag-recyclerview"],"_links":{"self":[{"href":"https:\/\/naps.com.mx\/blog\/wp-json\/wp\/v2\/posts\/1976","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/naps.com.mx\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/naps.com.mx\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/naps.com.mx\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/naps.com.mx\/blog\/wp-json\/wp\/v2\/comments?post=1976"}],"version-history":[{"count":22,"href":"https:\/\/naps.com.mx\/blog\/wp-json\/wp\/v2\/posts\/1976\/revisions"}],"predecessor-version":[{"id":2069,"href":"https:\/\/naps.com.mx\/blog\/wp-json\/wp\/v2\/posts\/1976\/revisions\/2069"}],"wp:attachment":[{"href":"https:\/\/naps.com.mx\/blog\/wp-json\/wp\/v2\/media?parent=1976"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/naps.com.mx\/blog\/wp-json\/wp\/v2\/categories?post=1976"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/naps.com.mx\/blog\/wp-json\/wp\/v2\/tags?post=1976"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}