Diferencia entre revisiones de «ListView»
Ir a la navegación
Ir a la búsqueda
Exemplo de cardview obtida deste enlace.
Línea 559: | Línea 559: | ||
<br /> | <br /> | ||
+ | ====Operación de baixa==== | ||
+ | * Para dar de baixa un elemento necesitamos gardar a posición clickeada polo usuario. | ||
+ | |||
+ | |||
+ | <br /> | ||
+ | =====Accedendo ao adaptador===== | ||
+ | : Supoñemos que non temos acceso ao array de datos (por estar definido localmente, por exemplo). | ||
+ | <syntaxhighlight lang="java" enclose="div" highlight="7-9"> | ||
+ | private void xestionarEventos(){ | ||
+ | findViewById(R.id.btnBaixa).setOnClickListener(new View.OnClickListener() { | ||
+ | @Override | ||
+ | public void onClick(View view) { | ||
+ | if (posElemListaSelec==-1) return; | ||
+ | |||
+ | ArrayAdapter<String> adapter = (ArrayAdapter)((ListView)findViewById(R.id.lsvLista)).getAdapter(); | ||
+ | String objeto = adapter.getItem(posElemListaSelec); | ||
+ | adapter.remove(objeto); | ||
+ | EditText et = findViewById(R.id.edtEditElemLista); | ||
+ | et.setText(""); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | ListView lsvLista = findViewById(R.id.lsvLista); | ||
+ | lsvLista.setOnItemClickListener(new AdapterView.OnItemClickListener() { | ||
+ | @Override | ||
+ | public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { | ||
+ | posElemListaSelec = i; | ||
+ | EditText et = findViewById(R.id.edtEditElemLista); | ||
+ | et.setText(datos.get(i)); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | |||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | : Liña 7: Ao non ter acceso ao array de datos, calquera operación a temos que facer a través do adaptador. Polo tanto necesitamos obter unha referencia ao adaptador da ListView. | ||
+ | : Liña 8: A través do adaptador podemos acceder ao elemento seleccionado pola posición que temos gardada previamente no método onItemClick. | ||
+ | : Liña 9: Eliminamos o elemento do adaptador. Automaticamente xa se refresca o ListView e desaparece o elemento. | ||
+ | |||
+ | <br /> | ||
+ | =====Accedendo ao array de datos===== | ||
+ | |||
+ | * Neste caso podemos acceder ao array de datos que está cargado no adaptador (polo telo definido a nivel de Activity, non localmente nun método). | ||
+ | <syntaxhighlight lang="java" enclose="div" highlight="6-8"> | ||
+ | findViewById(R.id.btnBaixa).setOnClickListener(new View.OnClickListener() { | ||
+ | @Override | ||
+ | public void onClick(View view) { | ||
+ | if (posElemListaSelec==-1) return; | ||
+ | |||
+ | datos.remove(posElemListaSelec); | ||
+ | ArrayAdapter adaptador = (ArrayAdapter)((ListView)findViewById(R.id.lsvLista)).getAdapter(); | ||
+ | adaptador.notifyDataSetChanged(); | ||
+ | EditText et = findViewById(R.id.edtEditElemLista); | ||
+ | et.setText(""); | ||
+ | } | ||
+ | }); | ||
+ | </syntaxhighlight> | ||
+ | : Liña 6: Eliminamos o elemento do array de datos. | ||
+ | : Liña 8-9: Necesitamos informar ao ListView que ten que recargar a lista, chamando ao método notifyDataSetChanged() do adaptador. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | <br /> | ||
+ | |||
====Operacións sobre o Adaptador==== | ====Operacións sobre o Adaptador==== | ||
Línea 575: | Línea 640: | ||
<br /> | <br /> | ||
+ | |||
====Facendo que o elemento da lista quede seleccionado==== | ====Facendo que o elemento da lista quede seleccionado==== | ||
Revisión del 11:25 16 nov 2020
Sumario
- 1 Introdución
- 2 Caso Base
- 2.1 Preparando a Activity
- 2.2 Código do Layoout
- 2.3 Cargando datos
- 2.4 Personalizando o deseño
- 2.5 Xestionando o evento Click sobre un elemento da lista
- 2.6 Accedendo ao elemento seleccionado da lista
- 2.7 Operacións sobre a lista
- 3 Caso Práctico 1
- 4 ListView usando un recurso XML ou un array dinámico
- 5 Caso Práctico 2: Utilizando un Layout con Ckeckboxes
- 6 Operacións especiais
- 7 Introdución
- 8 Engadindo as librerías
- 9 Caso Práctico
Introdución
- Un ListView é unha view de que lle permite ao usuario seleccionar un elemento.
- A diferencia dun Spinner unha lista amosa todos os seus elementos na pantalla.
- A imaxe recolle un exemplo de lista, cada item pode conter un só dato, ou múltiples datos. O primeiro caso é o que se vai ver neste curso.
- Ao igual que no Spinner usaremos unha fonte de datos (array estático, array dinñamico, recurso xml, etc) para enlazalo co adaptador e este co ListView.
- Tamén podemos facer uso de layouts 'predefinidos'.
- Os layout que se poden empregar se poden consultar en http://wiki.cifprodolfoucha.es/index.php?title=Spinner#Caso_pr.C3.A1ctico
- O código fonte de cada layout se pode consultar en https://github.com/aosp-mirror/platform_frameworks_base/tree/master/core/res/res/layout
- Todo o visto có Spinner no uso de adaptadores pódese empregar neste view tendo en conta estas diferenzas:
- Os layout 'predefinidos' son de tipo listview, non spinner.
- A xestión de eventos sobre un elemento da lista (seleccionalo) se fai coa interface OnItemClickListener.
- Se queremos que ao premer sobre a lista, visualmente apareza seleccionado o elemento (digo visualmente, non queda seleccionado a nivel de programación) podemos cambiar estas propiedades no deseñador de Layout sobre o ListView:
android:choiceMode="singleChoice"
android:listSelector="@color/colorPrimary"
- Nota: @color/colorPrimary é un recurso de tipo 'color' cunha cor definida.
- Nota Importante: Na actualidade recoméndase empregar o RecyclerView en vez do ListView, xa que consume moita menos memoria.
- Un ListView vai 'xerar' todos os compoñentes gráficos que conforman cada fila para todos os elementos da lista, mentres que o RecyclerView soamente xera aqueles compoñentes que se visualizan.
Caso Base
- O que imos aprender en primeiro lugar é o funcionamento básico da lista.
- Como cargar datos na lista.
- Como modificar visualmente o aspecto de cada elemento da lista.
- Como xestionar o evento de click sobre un elemento da lista.
- Como acceder ao elemento seleccionado da lista.
- Como borrar, modificar ou engadir novos elementos á lista.
- Posteriormente veremos outras posibilidades que nos brinda este control
Preparando a Activity
- Imos crear unha Activity que visualmente teña este aspecto.
- Dentro do paquete Adaptadores crear unha nova 'Empty Activity' de nome: UD04_01_ListViews_base de tipo Launcher.
- Modifica o arquivo AndroidManifiest.xml e engade unha label á activity como xa vimos na creación do proxecto base.
Código do Layoout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".adaptadores.UD04_01_ListViews_base">
<Button
android:id="@+id/btnAlta"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Alta"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btnBaixa"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/btnBaixa"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Baixa"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btnModificar"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btnAlta" />
<Button
android:id="@+id/btnModificar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Modificar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btnBaixa" />
<EditText
android:id="@+id/edtEditElemLista"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ems="10"
android:hint="Texto Elemento Lista"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline" />
<ListView
android:id="@+id/lsvLista"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/holo_blue_dark"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
Cargando datos
- O primeiro que temos que lograr facer é cargar os datos na lista.
- Isto o podemos facer de dúas formas:
- Graficamente, a través da propiedade entreis do ListView.
- Por código, facendo uso dun ArrayAdapter.
Cargando datos dende o Layout
- Primeiro debemos crear un recurso nun dos arquivos /res/values de tipo 'array'.
- No exemplo está creado no arquivo /res/values/strings.xml.
<array name="array_datos_lista"> <item>Valor 1</item> <item>Valor 2</item> <item>Valor 3</item> </array>
- Estes son valores que vai cargar a lista.
- Nota: Fixarse que estes valores poden estar traducidos a diferentes idiomas coma xa vimos na sección de internacionalización.
Cargando datos dende o código
- Nota: Quitamos a carga de datos se a temos na propiedade 'entries' do ListView como vimos no punto anterior.
- Para iso temos que facer uso dun Adapter, concretamente imos a empregar o ArrayAdapter
- Lembrar que xa expliquei o que era un adaptador.
- Se nos fixamos nos contructores do adaptador:
- Nos imos a empregar o terceiro constructor.
- Necesitimos indicarlle o layout que vai empregar para visualizar os elementos da lista. Podemos empregar calquera sempre que teña a lo menos un TextView.
- Android proporciona xa uns predeterminados que podemos empregar, concretamente : android.R.layout.simple_list_item_1 (podedes ver o deseño dende Android Studio premendo a tecla Control e premendo có rato sobre simple_list_item_1).
- Por outra banda necesitamos algún tipo de array que garde os datos.
public class UD04_01_ListViews_base extends AppCompatActivity { private void cargarDatos(){ String[]datos = getResources().getStringArray(R.array.array_datos_lista); ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,datos); ListView listView = findViewById(R.id.lsvLista); listView.setAdapter(adapter); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_u_d04_01__list_views_base); cargarDatos(); } }
- Liña 5: Como vemos obtemos os datos do string-array creado en /res/values no punto anterior.
- Liña 7: Creamos un adaptador empregando un layout do S.O. e mandamos os datos.
- Liña 9: Asociamos o adaptador á lista (se non facemos isto non se cargará ningún dato).
- Podemos facer unha variante deste código e facer que os datos veñan dun ArrrayList:
private void cargarDatos(){
ArrayList<String>datos = new ArrayList<>(Arrays.asList("Valor 1","Valor 2", "Valor 3"));
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,datos);
ListView listView = findViewById(R.id.lsvLista);
listView.setAdapter(adapter);
}
Personalizando o deseño
- Antes vimos que no segundo parámetro temos que enviarlle o id do layout que vai representar cada un dos elementos da lista.
- Nos podemos crear o noso propio Layout.
- Por exemplo:
Layout: elemento_listview
::<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="VALOR:"
android:textColor="@android:color/holo_purple"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/txvElemLista"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="TextView"
app:layout_constraintStart_toEndOf="@+id/textView"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- Agora imos decirlle ao adaptador que cargue este deseño, pero como dentro do mesmo hai dous TextView, temos que decirlle cal deles debe empregar para pasar o dato da fonte de datos ao view.
- Para iso empregamos outro dos contructores vistos anteriormente:
private void cargarDatos(){ ArrayList<String>datos = new ArrayList<>(Arrays.asList("Valor 1","Valor 2", "Valor 3")); ArrayAdapter<String> adapter = new ArrayAdapter<>(this, R.layout.elemento_listview,R.id.txvElemLista,datos); ListView listView = findViewById(R.id.lsvLista); listView.setAdapter(adapter); }
- Liña 3: Fixarse en dúas cousas: Cargamos o layout deseñado por nos e enviamos como tecer parámetro o id do textview que se atopa dentro do layout.
Xestionando o evento Click sobre un elemento da lista
- Para xestionar o evento Click debemos empregar a interface OnItemClickListener.
- NOTA IMPORTANTE: Cando prememos nun elemento da lista este non queda seleccionado polo que non podemos empregar ningún método o interface que indique 'selected'.
private void xestionarEventos(){
ListView lsvLista = findViewById(R.id.lsvLista);
lsvLista.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(getApplicationContext(), adapterView.getItemAtPosition(i).toString(),Toast.LENGTH_SHORT).show();
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_u_d04_01__list_views_base);
cargarDatos();
xestionarEventos();
}
- Liña 5: No método da interface onItemClick vai vir como parámetros:
- O AdapterView, a través do cal
- Podemos acceder aos elementos que están cargados na lista.
- Podemos recuperar a referencia ao ArrayAdapter.
- O View que foi premido (lembrar que se estamos a facer o exemplo, o view agora mesmo é o layout que fixemos con dous textview.
- i é a posición do elemento seleccionado.
- l é un identificador de fila (que non imos empregar).
O anterior é equivalente e isto se temos acceso aos array de datos:
public class UD04_01_ListViews_base extends AppCompatActivity {
private ArrayList<String>datos = new ArrayList<>(Arrays.asList("Valor 1","Valor 2", "Valor 3"));
private void cargarDatos(){
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, R.layout.elemento_listview,R.id.txvElemLista,datos);
ListView listView = findViewById(R.id.lsvLista);
listView.setAdapter(adapter);
}
private void xestionarEventos(){
ListView lsvLista = findViewById(R.id.lsvLista);
lsvLista.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(getApplicationContext(), datos.get(i).toString(),Toast.LENGTH_SHORT).show();
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_u_d04_01__list_views_base);
cargarDatos();
xestionarEventos();
}
}
- Liña 3: Definimos o array a nivel de Activity para poder acceder a el dende calquera parte.
- Liña 17: Accedemos á posición do array.
- Curiosidade: O parámetro 'view' nos permite acceder aos views que están dentro do layout que deseñamos.
- Por exemplo:
lsvLista.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
TextView tv = view.findViewById(R.id.txvElemLista);
tv.setTextColor(Color.RED);
Toast.makeText(getApplicationContext(), datos.get(i).toString(),Toast.LENGTH_SHORT).show();
}
});
Accedendo ao elemento seleccionado da lista
- O ListView non selecciona ningún elemento cando prememos nela, polo que non podemos empregar os métodos como: lista.getSelectedItem()
- Este tipo de chamadas devolverán sempre null no caso do ListView (si funcionan cun spinner).
- A única forma de saber cal é o elemento que premeu o usuario é gardando a posición nunha propiedade da Activity, no método onItemClick que vimos anteiormente. Veremos o seu uso na operación de baixa.
Operacións sobre a lista
- Podemos facer alta, baixas e modificacións.
- Ditas operacións as podemos facer sobre o Array onde temos gardados os datos (sempre que estea definido a nivel de Activity ou de forma global) ou sobre o adaptador asociado á ListView.
- O ArrayAdapter está 'cheo' de métodos para engadir, borrar e modificar elementos da lista.
- Por exemplo:
- add(T object): Engade un elemento á lista de elementos.
- addAll(Collection<? extends T> collection): Engade unha colección.
- getCount(): Devolve o número de elementos da lista.
- getItem(int position): Devolve o elemento da lista en base a súa posición (empeza en 0)
- insert(T object, int index) : Engade un elemento na posición indicada.
- remove(T object): Elimina un elemento da lista.
- clear(): Borra todos os elementos da lista.
- Imos velos das dúas formas:
Operación de Alta
Accedendo ao adaptador
- Supoñemos que non temos acceso ao array de datos (por estar definido localmente, por exemplo).
private void xestionarEventos(){
findViewById(R.id.btnAlta).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EditText et = findViewById(R.id.edtEditElemLista);
if (et.getText().toString().length()==0) return;
ArrayAdapter adaptador = (ArrayAdapter)((ListView)findViewById(R.id.lsvLista)).getAdapter();
adaptador.add(et.getText().toString());
}
});
findViewById(R.id.btnBaixa).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (posElemListaSelec==-1) return;
ArrayAdapter<String> adapter = (ArrayAdapter)((ListView)findViewById(R.id.lsvLista)).getAdapter();
String objeto = adapter.getItem(posElemListaSelec);
adapter.remove(objeto);
EditText et = findViewById(R.id.edtEditElemLista);
et.setText("");
}
});
ListView lsvLista = findViewById(R.id.lsvLista);
lsvLista.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
posElemListaSelec = i;
EditText et = findViewById(R.id.edtEditElemLista);
et.setText(datos.get(i));
}
});
}
- Liña 8: Ao non ter acceso ao array de datos, calquera operación a temos que facer a través do adaptador. Polo tanto necesitamos obter unha referencia ao adaptador da ListView.
- Liña 9: A través do adaptador podemos engadir o novo texto.
Accedendo ao array de datos
- Neste caso podemos acceder ao array de datos que está cargado no adaptador (polo telo definido a nivel de Activity, non localmente nun método).
findViewById(R.id.btnAlta).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EditText et = findViewById(R.id.edtEditElemLista);
if (et.getText().toString().length()==0) return;
ArrayAdapter adaptador = (ArrayAdapter)((ListView)findViewById(R.id.lsvLista)).getAdapter();
datos.add(et.getText().toString());
adaptador.notifyDataSetChanged();
et.setText("");
}
});
- Liña 8: Añadimos o elemento ao array de datos.
- Liña 9: Necesitamos informar ao ListView que ten que recargar a lista, chamando ao método notifyDataSetChanged() do adaptador.
Operación de Modificar
- Necesitamos ter gardado nun atributo da clase, a posición do elemento seleccionado ao premer sobre a lista (como xa vimos nun exemplo anterior)
Accedendo ao adaptador
- Supoñemos que non temos acceso ao array de datos (por estar definido localmente, por exemplo).
- O máis doado neste caso é borrar e dar de alta o novo elemento.
private void xestionarEventos(){
findViewById(R.id.btnModificar).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EditText et = findViewById(R.id.edtEditElemLista);
if ((et.getText().toString().length()==0) || (posElemListaSelec==-1)) return;
ArrayAdapter adaptador = (ArrayAdapter)((ListView)findViewById(R.id.lsvLista)).getAdapter();
String datoSel = (String)adaptador.getItem(posElemListaSelec);
adaptador.remove(datoSel);
String datoNuevo = et.getText().toString();
adaptador.insert(datoNuevo,posElemListaSelec);
}
});
ListView lsvLista = findViewById(R.id.lsvLista);
lsvLista.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
posElemListaSelec = i;
EditText et = findViewById(R.id.edtEditElemLista);
et.setText(datos.get(i));
}
});
}
- Liña 11: Borramos o elemento seleccionado.
- Liña 13: Engadimos o novo elemento.
- NOTA IMPORTANTE: Se estamos a traballar con obxectos (é dicir, o que gardamos como elemento da lista é un obxecto dunha clase definida por nos, no que sobrescribimos o método toString para indicar o que queremos visualizar), podemos non borrar e crear un novo obxecto, xa que cando obtemos o elemento seleccionado estamos a obter a dirección de memoria onde ese obxecto está aloxado.
- Polo tanto se modificamos o obxecto seleccionado é como si modificaramos o elemento do array de datos e podemos empregar a segunda forma (ven explicado a continuación) informando ao adaptador que houbo un cambio nos datos.
Accedendo ao array de datos
- Neste caso podemos acceder ao array de datos que está cargado no adaptador (polo telo definido a nivel de Activity, non localmente nun método).
findViewById(R.id.btnModificar).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EditText et = findViewById(R.id.edtEditElemLista);
if (et.getText().toString().length()==0) return;
ArrayAdapter adaptador = (ArrayAdapter)((ListView)findViewById(R.id.lsvLista)).getAdapter();
datos.set(posElemListaSelec,et.getText().toString());
adaptador.notifyDataSetChanged();
}
});
- Liña 8: Modificamos o elemento do array de datos.
- Curiosidade: Podemos acceder ao view seleccionado mediante esta forma:
View elemview = adaptador.getView(posElemListaSelec,View.inflate(getApplicationContext(),R.layout.elemento_listview,null),null);
((TextView) elemview.findViewById(R.id.txvElemLista)).setText(et.getText().toString());
Operación de baixa
- Para dar de baixa un elemento necesitamos gardar a posición clickeada polo usuario.
Accedendo ao adaptador
- Supoñemos que non temos acceso ao array de datos (por estar definido localmente, por exemplo).
private void xestionarEventos(){
findViewById(R.id.btnBaixa).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (posElemListaSelec==-1) return;
ArrayAdapter<String> adapter = (ArrayAdapter)((ListView)findViewById(R.id.lsvLista)).getAdapter();
String objeto = adapter.getItem(posElemListaSelec);
adapter.remove(objeto);
EditText et = findViewById(R.id.edtEditElemLista);
et.setText("");
}
});
ListView lsvLista = findViewById(R.id.lsvLista);
lsvLista.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
posElemListaSelec = i;
EditText et = findViewById(R.id.edtEditElemLista);
et.setText(datos.get(i));
}
});
}
- Liña 7: Ao non ter acceso ao array de datos, calquera operación a temos que facer a través do adaptador. Polo tanto necesitamos obter unha referencia ao adaptador da ListView.
- Liña 8: A través do adaptador podemos acceder ao elemento seleccionado pola posición que temos gardada previamente no método onItemClick.
- Liña 9: Eliminamos o elemento do adaptador. Automaticamente xa se refresca o ListView e desaparece o elemento.
Accedendo ao array de datos
- Neste caso podemos acceder ao array de datos que está cargado no adaptador (polo telo definido a nivel de Activity, non localmente nun método).
findViewById(R.id.btnBaixa).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (posElemListaSelec==-1) return;
datos.remove(posElemListaSelec);
ArrayAdapter adaptador = (ArrayAdapter)((ListView)findViewById(R.id.lsvLista)).getAdapter();
adaptador.notifyDataSetChanged();
EditText et = findViewById(R.id.edtEditElemLista);
et.setText("");
}
});
- Liña 6: Eliminamos o elemento do array de datos.
- Liña 8-9: Necesitamos informar ao ListView que ten que recargar a lista, chamando ao método notifyDataSetChanged() do adaptador.
Operacións sobre o Adaptador
- O ArrayAdapter está 'cheo' de métodos para engadir, borrar e modificar elementos da lista.
- Por exemplo:
- add(T object): Engade un elemento á lista de elementos.
- addAll(Collection<? extends T> collection): Engade unha colección.
- getCount(): Devolve o número de elementos da lista.
- getItem(int position): Devolve o elemento da lista en base a súa posición (empeza en 0)
- insert(T object, int index) : Engade un elemento na posición indicada.
- remove(T object): Elimina un elemento da lista.
- clear(): Borra todos os elementos da lista.
Facendo que o elemento da lista quede seleccionado
- Como comentei anteriormente, a lista non selecciona o elemento ao premer sobre el.
- Realmente estamos a facer click.
- Para solucionalo podemos facer o seguinte:
- O problema que ten esta solución é que ao borrar un elemento da lista, 'a fila' mantense seleccionada.
- O poderíamos intentar arranxar accedendo ao View seleccionado (no método onItemClick da interface onItemClickListener, gardando o View nun atributo a nivel de Activity) e cambiando a cor de fondo a branco cando se dea de baixa.
- Outra forma é empregar un recurso de Android denominado 'selectores'.
- Os selectores son recursos que se crean no cartafol /res/drawable/. Son arquivos de texto onde se especifica, segundo o estado no que se atope un View, cambiar o que se vai debuxar (normalmente a cor de fondo).
- Para probalo necesitamos acceder ao View que visualiza cada elemento da lista. Polo tanto non podemos empregar o Layout que subministra o S.O.
- Como nun punto anterior xa empregamos un deseño propio, imos a empregalo.
- Unha vez temos o selector, temos que asignar dito selector ao Constraint que deseñamos previamente.
- Imos a asocialo á propiedade background do mesmo.
- Agora a nivel de código imos a indicarlle que cargue o deseño personalizado:
private void cargarDatos(){
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, R.layout.elemento_listview,R.id.txvElemSpinner,datos);
ListView listView = findViewById(R.id.lsvLista);
listView.setAdapter(adapter);
}
- E como último paso temos que facer que cando se seleccione un elemento da lista, o view sexa 'seleccionado' e así se activaría o estado establecido no selector.
ListView lsvLista = findViewById(R.id.lsvLista);
lsvLista.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
view.setSelected(true);
posElemListaSelec = i;
EditText et = findViewById(R.id.edtEditElemLista);
et.setText(datos.get(i));
}
});
Caso Práctico 1
- Partimos que xa temos creado o proxecto inicial como xa indicamos anteriormente.
- Se non o temos creado antes, crearemos un novo paquete de nome: Adaptadores como un subpaquete do teu paquete principal.
XML do Layout
- Definimos no Layout unha vista de tipo ListView (Liñas 14-17).
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical" >
6
7 <TextView
8 android:layout_width="match_parent"
9 android:textSize="20sp"
10 android:layout_height="wrap_content"
11 android:text="Selecciona unha froita" />
12
13 <ListView
14 android:id="@+id/lvFroitas_UD04_01_ListViews"
15 android:layout_width="match_parent"
16 android:layout_height="wrap_content" />
17
18 </LinearLayout>
Código da Activity
- A filosofía do código Java é moi semellante ao do Spinner.
1 package es.cursoandroid.cifprodolfoucha.aprendiendo.Adaptadores;
2
3 import android.app.Activity;
4 import android.os.Bundle;
5 import android.view.View;
6 import android.widget.AdapterView;
7 import android.widget.ArrayAdapter;
8 import android.widget.ListView;
9 import android.widget.TextView;
10 import android.widget.Toast;
11
12 import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
13
14 public class UD04_01_ListViews extends Activity {
15
16 private void cargarListas(){
17 //Fonte de datos
18 String[] froitas = new String[] { "Pera", "Mazá", "Plátano" };
19
20 //Enlace do adaptador coa fonte de datos
21 ArrayAdapter<String> adaptador = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, froitas);
22
23 ListView lvFroitas = findViewById(R.id.lvFroitas_UD04_01_ListViews);
24 //Enlace do adaptador co ListView
25 lvFroitas.setAdapter(adaptador);
26 }
27 private void xestionarEventos(){
28
29 ListView lvFroitas = findViewById(R.id.lvFroitas_UD04_01_ListViews);
30 //Escoitador
31 lvFroitas.setOnItemClickListener(new AdapterView.OnItemClickListener() {
32
33 @Override
34 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
35 // TODO Auto-generated method stub
36 //Toast.makeText(getBaseContext(), "Seleccionaches: " + parent.getItemAtPosition(position), Toast.LENGTH_SHORT).show();
37 Toast.makeText(getApplicationContext(), "Seleccionaches: " + ((TextView) view).getText(), Toast.LENGTH_SHORT).show();
38
39 }
40 });
41 }
42
43 @Override
44 protected void onCreate(Bundle savedInstanceState) {
45 super.onCreate(savedInstanceState);
46 setContentView(R.layout.activity_ud04_01__list_views);
47
48 cargarListas();
49 xestionarEventos();
50 }
51 }
- Liña 18: Ao igual que no Spinner, creamos unha fonte de datos, neste caso cun array estático.
- Liña 21: Do mesmo xeito creamos o adaptador
- Liña 25: E finalmente, vinculamos o adaptador ao ListView
- Liña 31: O Escoitador asociado ao ListView.
- Liñas 36,37: Ao igual que no spinner, neste caso a vista que recibimos cando facemos click nun ítem da view é do tipo TextView.
ListView usando un recurso XML ou un array dinámico
- Neste caso funciona igual que o visto no Spinner que fai uso dun adaptador.
Caso Práctico 2: Utilizando un Layout con Ckeckboxes
- Partimos que xa temos creado o proxecto inicial como xa indicamos anteriormente.
- Se non o temos creado antes, crearemos un novo paquete de nome: Adaptadores como un subpaquete do teu paquete principal.
- Dentro do paquete Adaptadores crear unha nova 'Empty Activity' de nome: UD04_02_ListViews de tipo Launcher e sen compatibilidade.
- Modifica o arquivo AndroidManifiest.xml e engade unha label á activity como xa vimos na creación do proxecto base.
- Como comentamos ao inicio, ao crear o adaptador podemos facer uso de varios layouts xa definidos polo S.O. Android.
- Un destes layouts permite que cada elemento da lista tenga un 'checkbox' asociado.
- Para que funcione, debemos de:
- Poñer no layout o atributo: android:choiceMode="multipleChoice"
- Ou ben ter unha referencia ao ListView e cambia dito atributo por programación: refLista.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
- O layout que imos utilizar é: R.layout.simple_list_item_checked que podemos comprobar que está formado por un CheckedTextView.
- Se necesitamos programar algo cando se preme un elemento da lista non ten problema ningún, se fería como no Spinner. A única diferenza é que o View que ven no método 'onItemClick' da interface e de tipo 'CheckedTextView'. Facendo un cast a dito tipo, accederemos ao texto e se está checked ou non.
- O máis complicado será no caso que necesitemos, cada vez que se pulsa un elemento, percorrer toda a lista checkeando cales dos elementos están marcados.
- Para facer isto temos varias aproximacións:
- Opción a)
- Definir un ArrayList<String> e gardar nel os elementos que imos seleccionando ou quitando da lista os elementos que xa non están seleccionados.
- Para saber cando un elemento está seleccionado ou non:
1 private ArrayList<String>datos = new ArrayList<>(); 2 ............... 3 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 4 // TODO Auto-generated method stub 5 CheckedTextView c = (CheckedTextView)view; 6 if (c.isChecked()){ 7 datos.add(c.getText().toString()); 8 } 9 else { 10 datos.remove(c.getText().toString()); 11 } 12 }
- Opción b)
- Facer uso da clase SparseBooleanArray e do método getCheckedItemPositions o cal devolve un obxecto da clase SparseBooleanArray coas posicións dos elementos seleccionados.
- Para facer iso disto temos:
1 SparseBooleanArray elems = referenciaLista.getCheckedItemPositions(); 2 for(int cont=0; cont < referenciaLista.getCount();cont++){ 3 if (elems.get(cont)){ 4 // Está seleccionado 5 } 6 }
XML do Layout
1 <?xml version="1.0" encoding="utf-8"?>
2 <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto"
4 xmlns:tools="http://schemas.android.com/tools"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent"
7 tools:context=".Adaptadores.UD04_02_ListViews">
8
9 <LinearLayout
10 android:layout_width="0dp"
11 android:layout_height="149dp"
12 android:layout_marginEnd="32dp"
13 android:layout_marginStart="32dp"
14 android:layout_marginTop="8dp"
15 android:orientation="vertical"
16 app:layout_constraintEnd_toEndOf="parent"
17 app:layout_constraintStart_toStartOf="parent"
18 app:layout_constraintTop_toTopOf="parent">
19
20 <ListView
21 android:id="@+id/lvCoches_UD04_02_ListViews"
22 android:layout_width="match_parent"
23 android:layout_height="0dp"
24 android:layout_marginEnd="8dp"
25 android:layout_marginStart="8dp"
26 android:layout_marginTop="8dp"
27 android:layout_weight="1"
28 android:choiceMode="multipleChoice">
29
30 </ListView>
31 </LinearLayout>
32
33 <TextView
34 android:id="@+id/tvSeleccionados_UD04_02_ListViews"
35 android:layout_width="0dp"
36 android:layout_height="wrap_content"
37 android:layout_marginBottom="8dp"
38 android:layout_marginEnd="8dp"
39 android:layout_marginStart="8dp"
40 android:textSize="24sp"
41 app:layout_constraintBottom_toBottomOf="parent"
42 app:layout_constraintEnd_toEndOf="parent"
43 app:layout_constraintStart_toStartOf="parent"
44 tools:text="Elementos seleccionados" />
45
46 </android.support.constraint.ConstraintLayout>
Código da Activity
1 package es.cursoandroid.cifprodolfoucha.aprendiendo.Adaptadores;
2
3 import android.app.Activity;
4 import android.os.Bundle;
5 import android.text.Html;
6 import android.util.SparseBooleanArray;
7 import android.view.View;
8 import android.widget.AdapterView;
9 import android.widget.ArrayAdapter;
10 import android.widget.CheckedTextView;
11 import android.widget.ListView;
12 import android.widget.TextView;
13 import android.widget.Toast;
14
15 import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
16
17 public class UD04_02_ListViews extends Activity {
18
19 private void cargarListas(){
20 //Fonte de datos
21 String[] coches = new String[] { "FORD", "OPEL", "SEAT","CITROEN","VOLKSWAGEN","ONDA" };
22
23 //Enlace do adaptador coa fonte de datos
24 ArrayAdapter<String> adaptador = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_checked, coches);
25
26 ListView lvCoches = findViewById(R.id.lvCoches_UD04_02_ListViews);
27 //Enlace do adaptador co ListView
28 lvCoches.setAdapter(adaptador);
29 }
30
31 private void xestionarEventos(){
32
33 final ListView lvCoches = findViewById(R.id.lvCoches_UD04_02_ListViews);
34
35 //Escoitador
36 lvCoches.setOnItemClickListener(new AdapterView.OnItemClickListener() {
37
38 @Override
39 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
40 // TODO Auto-generated method stub
41 CheckedTextView c = (CheckedTextView)view;
42 Toast.makeText(getApplicationContext(),c.getText(),Toast.LENGTH_LONG).show();
43
44 TextView mensaxe = findViewById(R.id.tvSeleccionados_UD04_02_ListViews);
45 mensaxe.setText("");
46 SparseBooleanArray elems = lvCoches.getCheckedItemPositions();
47 for(int cont=0; cont < lvCoches.getCount();cont++){
48 if (elems.get(cont)){
49 mensaxe.append(lvCoches.getItemAtPosition(cont).toString()+ Html.fromHtml("<br />"));
50 }
51 }
52
53 }
54 });
55 }
56
57
58 @Override
59 protected void onCreate(Bundle savedInstanceState) {
60 super.onCreate(savedInstanceState);
61 setContentView(R.layout.activity_ud04_02__list_views);
62
63 cargarListas();
64 xestionarEventos();
65 }
66 }
Operacións especiais
- CASO PRÁCTICO:
- Temos uns datos locais nun array baseados nunha clase na que existe un campo booleano que nos indica se temos ou non seleccionado o elemento.
- Temos una lista de selección múltiple de tipo checkbox no seu layout (android.R.layout.simple_list_item_checked | android:choiceMode="multipleChoice")
- Queremos que ao cargarse a lista, aparezan seleccionados os elementos do array que teñen a propiedade boolean a true.
- Posible Solución:
1 ListView lvLista = findViewById(R.id.id_lista); 2 ArrayList<MiClase> datos = new ArrayList<>(); 3 4 // CARGAMOS O ARRAY CON DATOS. PODEN VIR DUNHA BASE DE DATOS OU CALQUERA OUTRA FONTE 5 6 ArrayAdapter<MiClase> arrayAdapter = new ArrayAdapter<MiClase>(this,android.R.layout.simple_list_item_checked,datos); 7 lvLista.setAdapter(arrayAdapter); 8 9 for (int i=0;i<datos.size();i++) { 10 lvLista.setItemChecked(i,datos.get(i).getPropiedadeBoolean()); 11 }
Introdución
- O RecyclerView ten como función amosar ao usuario en forma de lista con scroll.
- A diferenza con respecto ao ListView ou GridView vistos ata o de agora, é que con cantidades altas de datos, este compoñente é moito máis eficiente que os dous anteriores.
- O RecyclerView xera todos os elementos da lista que se manden inicialmente, pero se engadimos novos elementos ou borramos non ten que volver a recrear toda a lista, soamente recrea os que sufriran algún cambio.
- En operacións de eliminación, o RecyclerView reutiliza os view´s que conforman cada un dos elementos da lista (de aí ven o seu nome 'recycler') de tal forma que ao engadir novos elementos 'reutiliza' os view´s creados previamente para engadir os novos datos.
- Un ArrayAdapter xera os views de todos os elementos da lista estean visualmente ou non visibles na lista e se hai algún cambio ten que volver a recrealos todos.
- Por outra banda, o compoñente CardView serve para deseñar a forma en como se presenta a información de cada compoñente de lista.
- Por exemplo, podemos indicar que cada elemento da lista que se amosa facendo uso do RecyclerView estea formado por unha ImageView e un TextView.
- Este compoñente permite presentar información en forma de grupos, empregando unha forma de 'tarxeta'.
Engadindo as librerías
- O primeiro que temas que facer é engadir as librerías que van permitir que fagamos uso de ditos compoñentes.
- Se arrastrades graficamente os compoñentes, ditas librerías xa que engaden automaticamente ao arquivo build.gradle (nivel de módulo)
1 implementation 'com.android.support:recyclerview-v7:28.0.0'
2 implementation 'com.android.support:cardview-v7:28.0.0'
Caso Práctico
- Partimos que xa temos creado o proxecto inicial como xa indicamos anteriormente.
- Se non o temos creado antes, crea un paquete de nome Adaptadores como un subpaquete do teu paquete principal.
- Dentro do paquete Adaptadores, crearemos un novo paquete de nome: Checkboxes.
- Imos crear a seguinte Activity:
- Podedes descargar as imaxes dos planetas:
- Dentro do paquete Adaptadores crear unha nova 'Empty Activity' de nome: UD04_01_RecycleViewCardView de tipo Launcher e sen compatibilidade.
- Modifica o arquivo AndroidManifiest.xml e engade unha label á activity como xa vimos na creación do proxecto base.
- O layout asociado a dita activity terá un RecycleView ocupando o 100% do espazo cun margin superior de 24dp´s:
1 <?xml version="1.0" encoding="utf-8"?>
2 <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto"
4 xmlns:tools="http://schemas.android.com/tools"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent"
7 tools:context=".UD2.Adaptadores.UD04_01_RecycleViewCardView">
8
9 <android.support.v7.widget.RecyclerView
10 android:id="@+id/rvwRecycleView"
11 android:layout_width="match_parent"
12 android:layout_height="match_parent"
13 android:layout_marginTop="24dp"
14 app:layout_constraintBottom_toBottomOf="parent"
15 app:layout_constraintEnd_toEndOf="parent"
16 app:layout_constraintStart_toStartOf="parent"
17 app:layout_constraintTop_toTopOf="parent" />
18 </android.support.constraint.ConstraintLayout>
Creando o deseño do CardView
- O CardView ven ser coma un layout que representa como se van visualizar cada unha das filas que conforman o RecycleView.
- Polo tanto creamos un arquivo en /res/layout, un arquivo de nome 'card_layout_ud04_01_recycleviewcardview'.
- Agora engadimos o layout que queremos que teña cada fila e os compoñentes que queiramos que aparezan.
- Terá que engadirse o layout dentro da etiqueta <CardView>.
- No exemplo imos facer que apareza unha imaxe e un texto asociado a dita imaxe e imos empregar un ContraintLayout para facelo (se podería empregar calquera dos que vimos).
- Fixarse que:
- Na altura do layout e do CardView, imos poñer 'wrap_content' para que soamente ocupe o alto do compoñente que sexa máis alto (neste exemplo a foto).
- O ancho e alto da imaxe vai ser de 100x100 dp´s e desprazada á esquerda.
- O texto ocupa todo o espazo restante e está centrado con respecto á foto. Ten unha separación esquerda con respecto á foto e un tamaño de texto grande.
- O texto ten unha cor vermella defina por nos nun arquivo de recurso /res/values/
1 <?xml version="1.0" encoding="utf-8"?>
2 <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto"
4 xmlns:tools="http://schemas.android.com/tools"
5 android:layout_width="match_parent" android:layout_height="wrap_content">
6
7 <android.support.constraint.ConstraintLayout
8 android:id="@+id/ConstraintLayout"
9 android:layout_width="match_parent"
10 android:layout_height="wrap_content">
11
12 <ImageView
13 android:id="@+id/imgImaxe_UD04_01_CardLayout"
14 android:layout_width="100dp"
15 android:layout_height="100dp"
16 android:contentDescription="Imaxe"
17 app:layout_constraintEnd_toStartOf="@+id/tvTexto_UD04_01_CardView"
18 app:layout_constraintStart_toStartOf="parent"
19 app:layout_constraintTop_toTopOf="parent"
20 app:srcCompat="@mipmap/ic_launcher2" />
21
22 <TextView
23 android:id="@+id/tvTexto_UD04_01_CardView"
24 android:layout_width="0dp"
25 android:layout_height="wrap_content"
26 android:paddingStart="5dp"
27 android:text="Texto a amosar por fila"
28 android:textColor="@color/corvermello"
29 android:textSize="24sp"
30 app:layout_constraintBottom_toBottomOf="parent"
31 app:layout_constraintEnd_toEndOf="parent"
32 app:layout_constraintStart_toEndOf="@+id/imgImaxe_UD04_01_CardLayout"
33 app:layout_constraintTop_toTopOf="parent" />
34 </android.support.constraint.ConstraintLayout>
35 </android.support.v7.widget.CardView>
- Fixarse que temos unha serie de propiedades específicas do cardview:
- Podedes consultar a lista completa neste enlace.
- Entre as que imos modificar están:
- cardBackgroundColor: Cor de fondo da tarxeta
- cardCornerRadius: O perfil redondeado das tarxetas
- cardElevation: Elevación (Material Design)
- contentPadding: Padding de todo o contido que está dentro da tarxeta.
- Para separar unha tarxeta de outra podemos facer uso dos margin a nivel de CardView
1 <?xml version="1.0" encoding="utf-8"?>
2 <?xml version="1.0" encoding="utf-8"?>
3 <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
4 xmlns:app="http://schemas.android.com/apk/res-auto"
5 xmlns:tools="http://schemas.android.com/tools"
6 android:layout_width="match_parent"
7 android:layout_height="wrap_content"
8 android:layout_margin="5dp"
9 app:cardBackgroundColor="#81C784"
10 app:cardCornerRadius="12dp"
11 app:cardElevation="3dp"
12 app:contentPadding="4dp">
13
14 <android.support.constraint.ConstraintLayout
15 android:id="@+id/ConstraintLayout"
16 android:layout_width="match_parent"
17 android:layout_height="wrap_content">
18
19 <ImageView
20 android:id="@+id/imgImaxe_UD04_01_CardLayout"
21 android:layout_width="100dp"
22 android:layout_height="100dp"
23 android:contentDescription="Imaxe"
24 app:layout_constraintEnd_toStartOf="@+id/tvTexto_UD04_01_CardView"
25 app:layout_constraintStart_toStartOf="parent"
26 app:layout_constraintTop_toTopOf="parent"
27 app:srcCompat="@mipmap/ic_launcher2" />
28
29 <TextView
30 android:id="@+id/tvTexto_UD04_01_CardView"
31 android:layout_width="0dp"
32 android:layout_height="wrap_content"
33 android:paddingStart="5dp"
34 android:text="Texto a amosar por fila"
35 android:textColor="@color/corvermello"
36 android:textSize="24sp"
37 app:layout_constraintBottom_toBottomOf="parent"
38 app:layout_constraintEnd_toEndOf="parent"
39 app:layout_constraintStart_toEndOf="@+id/imgImaxe_UD04_01_CardLayout"
40 app:layout_constraintTop_toTopOf="parent" />
41 </android.support.constraint.ConstraintLayout>
42 </android.support.v7.widget.CardView>
Creando o Adaptador
- Un adaptador:
- é un elemento intermediario entre unha fonte de datos (XML, Arrays, Ficheiros, BBDD) e un interface de usuario que amosa eses datos, por exemplo un Spinner, unha lista de Selección, etc.
- Por cada dato crea unha View e a representa.
- É o responsable de xerar todos os elementos de representación asociados aos datos. Imaxinar que cada ítem estivera formado por dous subcompoñentes: nome de persoa e foto. O adaptador debe ser quen de poder representar iso.
- No caso do RecycleView, vai empregar un adaptador que deriva da clase RecycleView.Adapter.
- Polo tanto imos crear unha clase que derive dela.
- Ao facelo dará un erro no que se nos informa que debemos de implementar unha serie de métodos.
1 package cifprodolfoucha.cursoandroid.aprendiendo.UD2.Adaptadores;
2
3 import android.support.annotation.NonNull;
4 import android.support.v7.widget.RecyclerView;
5 import android.view.ViewGroup;
6
7 public class RecycleViewAdapter_UD04_01_RecycleViewCardView extends RecyclerView.Adapter {
8 @NonNull
9 @Override
10 public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
11 return null;
12 }
13
14 @Override
15 public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
16
17 }
18
19 @Override
20 public int getItemCount() {
21 return 0;
22 }
23 }
- Como vemos se implementan os seguintes métodos:
- getItemCount(): Ten que devolver o número de elementos que se van visualizar na lista.
- onCreateViewHolder(): Este método ten que devolver un obxecto da clase ViewHolder a cal é empregada para visualizar o contido da lista. Será na clase ViewHolder onde 'cargaremos' o deseño de fila feito no paso anterior.
- onBindViewHolder(): Este método recibe o ViewHolder do método anterior e asociamos a cada compoñente gráfico de dito View o dato que queremos que visualice.
- Neste adaptador é onde teremos que 'obter' os datos que conformarán as filas.
- Poderíamos obtelos dunha consulta a unha base de datos ou de calquera outra fonte (internet, un arquivo,...).
- No exemplo imos definilos localmente...
- No noso exemplo tedes que descargar imaxes de varios planetas (eu o fixen con 5) e gardalas no cartafol /res/drawable
- Os datos serán os seguintes (adaptalos ao voso caso):
1 package cifprodolfoucha.cursoandroid.aprendiendo.UD2.Adaptadores;
2
3 import android.support.annotation.NonNull;
4 import android.support.v7.widget.RecyclerView;
5 import android.view.ViewGroup;
6
7 public class RecycleViewAdapter_UD04_01_RecycleViewCardView extends RecyclerView.Adapter {
8
9 private String[] textos = {"Mercurio","Venus","Tierra","Jupiter","Saturno"};
10 private int[] imaxes = {R.drawable.mercurio,R.drawable.venus,R.drawable.tierra,R.drawable.jupiter,R.drawable.saturno};
11
12 @NonNull
13 @Override
14 public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
15 return null;
16 }
17 .......
- Nota: Fixarse na orde e como o número de elemento dentro do array se corresponde nos dous arrays có mesmo concepto (na posición 0 do array está o texto e a imaxe de Mercurio).
Definindo a clase ViewHolder
- Lembrar que o ViewHolder vai ser o que emprege o adaptador para 'cargar' os datos nos elementos gráficos que conforman cada fila (no noso exemplo, unha imaxe e un texto).
- Creamos por tanto unha clase que derive de RecycleView.ViewHolder (poderíamos creala dentro da clase RecycleAdapter) :
- Ao facelo daranos un erro de que hai que implementar un constructor. O facemos có asistente.
1 package cifprodolfoucha.cursoandroid.aprendiendo.UD2.Adaptadores;
2
3 import android.support.annotation.NonNull;
4 import android.support.v7.widget.RecyclerView;
5 import android.view.View;
6
7 public class ViewHolder_UD04_01_RecycleViewCardView extends RecyclerView.ViewHolder {
8
9 public ViewHolder_UD04_01_RecycleViewCardView(@NonNull View itemView) {
10 super(itemView);
11 }
12 }
- Esta clase vai ser a que nos permite acceder aos elementos gráficos definidos no CardView (o que está definido no layout que representa cada fila).
- Desta forma dende o Adapter imos poder cargar con datos os elementos gráficos.
- Ao constructor de esta clase vai vir (o veremos no seguinte paso) unha instancia de 'card_layout_ud04_01_recycleviewcardview'.
- Simplemente referenciaremos ditos controis para poder manexalos dende o adaptador.
- Modificamos o código polo seguinte:
1 public class ViewHolder_UD04_01_RecycleViewCardView extends RecyclerView.ViewHolder {
2
3 public ImageView itemImaxe;
4 public TextView itemTexto;
5
6 public ViewHolder_UD04_01_RecycleViewCardView(@NonNull View itemView) {
7 super(itemView);
8
9 itemImaxe = itemView.findViewById(R.id.imgImaxe_UD04_01_CardLayout);
10 itemTexto = itemView.findViewById(R.id.tvTexto_UD04_01_CardView);
11 }
12 }
Completando o funcionamento do adaptador
Instanciando o ViewHolder
- Como dixemos antes, o método onCreateViewHolder ten que 'devolver' un obxecto ViewHolder no que se atopan os elementos gráficos que conforman a fila.
- A clase na que se vai basear van ser a que fixemos nos pasos anteriores e que derivaba de ViewHolder (ViewHolder_UD04_01_RecycleViewCardView).
- Para facelo temos que realizar un proceso de 'inflar' o layout que conforma cada fila (card_layout_ud04_01_recycleviewcardview.xml) a un obxecto da clase View.
- E despois crear un obxecto da clase ViewHolder_UD04_01_RecycleViewCardView en base ao View obtido anteriormente.
- Para facer isto primeiro temos que 'converter' o layout onde están definidos os elementos gráficos que conforman a fila a un View.
- Para iso empregamos a clase LayoutInflater.
- Primeiro obtemos unha referencia a dita clase dunha das seguintes forma:
- LayoutInflater mInflater = (LayoutInflater) viewGroup.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- LayoutInflater mInflater = LayoutInflater.from(viewgroup.getContext());
- Despois chamamos ao método 'inflate' para que devolva por programación unha referencia ao layout onde están definidos os elementos gráficos da fila (un View):
- View v = mInflater.inflate(R.layout.card_layout_ud04_01_recycleviewcardview,viewGroup,false);
- E por último creamos o ViewHolder creando un obxecto da clase ViewHolder creada por nos previamente (ViewHolder_UD04_01_RecycleViewCardView) e pasando como parámetro no constructor o View anterior:
- RecyclerView.ViewHolder viewHolder = new ViewHolder_UD04_01_RecycleViewCardView(v);
1 @NonNull
2 @Override
3 public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
4
5 LayoutInflater mInflater = (LayoutInflater) viewGroup.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
6 //View view = (LayoutInflater.from(viewGroup.getContext()))
7 View v = mInflater.inflate(R.layout.card_layout_ud04_01_recycleviewcardview,viewGroup,false);
8 RecyclerView.ViewHolder viewHolder = new ViewHolder_UD04_01_RecycleViewCardView(v);
9
10 return viewHolder;
11 }
Engadindo datos ao ViewHolder
- Os datos, tedes que lembrar, que están definidos en dous arrays, pero podedes ter un único arrays de obxectos dunha clase e recollelos dese array.
- O que si ides ter sempre é a lo menos un array de elementos con información.
- Outro método que vimos que se creaba cando creamos o RecycleView.Adapter era o onBindViewHolder.
- Neste método imos a 'meter' os datos que queremos que aparezan no ViewHolder creado no paso anterior.^:
- Para iso temos que empregar o parámetro 'i' que indica o número de elemento do array sobre o que temos que buscar a información e despois asociala aos elementos gráficos.
- Por outra banda como o obxecto da clase ViewHolder pertence realmente á clase ViewHolder_UD04_01_RecycleViewCardView, podemos acceder aos seus elementos gráficos xa que están declarados como 'public' na definición da clase.
- O código queda como o seguinte:
1 @Override
2 public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
3
4 ViewHolder_UD04_01_RecycleViewCardView viewHolderMeu = (ViewHolder_UD04_01_RecycleViewCardView) viewHolder;
5 viewHolderMeu.itemImaxe.setImageResource(imaxes[i]);
6 viewHolderMeu.itemTexto.setText(textos[i]);
7 }
Implementando o método getItemCount
- Como indicamos anteriormente, dito método ten que devolver o número de elementos da lista, que debe de coincidir có número de elementos do array onde están os datos.
- Polo tanto:
1 @Override
2 public int getItemCount() {
3 return textos.length;
4 }
Paso final
- Por último temos que facer dúas cousas:
- 1º Paso: O RecycleView necesita un Layout Manager que lle diga como van distribuídos cada un dos elementos que van aparecer.
- A forma máis común de facelo é cun LinearLayout e que vaian en forma de fila, pero podemos empregar outras distribucións.
- Na imaxe anterior vemos:
- Exemplo de LinearLayout con distribución vertical (por defecto):
- RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
- Exemplo de LinearLayout con distribución horizontal:
- RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
- Exemplo de GridLayout con dúas columnas:
- RecyclerView.LayoutManager layoutManager = new GridLayoutManager(this,2);
- Na imaxe anterior vemos:
- Unha vez creado o LayoutManager hai que asocialo ao RecycleView.
- 2º Paso: Hai que crear unha instancia do adaptador creado por nos (RecycleViewAdapter_UD04_01_RecycleViewCardView) e asocialo ao RecycleView.
1 package cifprodolfoucha.cursoandroid.aprendiendo.UD2.Adaptadores;
2
3 import android.support.v7.app.AppCompatActivity;
4 import android.os.Bundle;
5 import android.support.v7.widget.GridLayoutManager;
6 import android.support.v7.widget.LinearLayoutManager;
7 import android.support.v7.widget.RecyclerView;
8
9 import cifprodolfoucha.cursoandroid.aprendiendo.R;
10
11 public class UD04_01_RecycleViewCardView extends AppCompatActivity {
12
13 @Override
14 protected void onCreate(Bundle savedInstanceState) {
15 super.onCreate(savedInstanceState);
16 setContentView(R.layout.activity_ud04_01__recycle_view_card_view);
17
18 RecycleViewAdapter_UD04_01_RecycleViewCardView recycleAdapter = new RecycleViewAdapter_UD04_01_RecycleViewCardView();
19
20 RecyclerView.LayoutManager layoutManager = new GridLayoutManager(this,2);
21 RecyclerView recyclerView = findViewById(R.id.rvwRecycleView);
22 recyclerView.setLayoutManager(layoutManager);
23 recyclerView.setAdapter(recycleAdapter);
24
25 }
26 }
Xestionar eventos de Click´s sobre os elementos
- Podemos modificar un par de propiedades do layout asociado ao cardview para que cando prememos apareza un efecto de 'selección' sobre o elemento premido.
1 <?xml version="1.0" encoding="utf-8"?>
2
3 <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
4 xmlns:app="http://schemas.android.com/apk/res-auto"
5 xmlns:tools="http://schemas.android.com/tools"
6 android:layout_width="match_parent"
7 android:layout_height="wrap_content"
8 android:layout_margin="5dp"
9 android:foreground="?android:attr/selectableItemBackground"
10 android:clickable="true"
11 android:focusable="true"
12 app:cardBackgroundColor="#81C784"
13 app:cardCornerRadius="12dp"
14 app:cardElevation="3dp"
15 app:contentPadding="4dp">
16
17 .....
- Podedes ler máis acerca deste tipo de animacións neste enlace.
- Se queremos xestionar o evento do Click o podemos facer:
- Sobre todo o conxunto de elementos que conforman a interface gráfica da fila.
- Sobre algún dos elementos que conforman a interface gráfica da fila.
- Caso a) Xestión do Click sobre todo o conxunto No primeiro caso temos que facer uso do obxecto itemView que se atopa dispoñible na clase ViewHolder e que representa o CardView con todo:
1 public class ViewHolder_UD04_01_RecycleViewCardView extends RecyclerView.ViewHolder { 2 3 public ImageView itemImaxe; 4 public TextView itemTexto; 5 6 public ViewHolder_UD04_01_RecycleViewCardView(@NonNull final View itemView) { 7 super(itemView); 8 9 itemImaxe = itemView.findViewById(R.id.imgImaxe_UD04_01_CardLayout); 10 itemTexto = itemView.findViewById(R.id.tvTexto_UD04_01_CardView); 11 12 itemView.setOnClickListener(new View.OnClickListener() { 13 @Override 14 public void onClick(View v) { 15 int posicion = getAdapterPosition(); 16 Toast.makeText(v.getContext(),"Pulsado elemento " + posicion + " da lista.",Toast.LENGTH_SHORT).show(); 17 } 18 }); 19 } 20 }
- Liña 15: Dispoñemos do método getAdapterPosition() que nos devolve a posición do elemento seleccionado da lista.
- Nota: Isto mesmo o podemos facer dende a clase 'RecycleViewAdapter_UD04_01_RecycleViewCardView' xa que lembrar que o view que pasamos como parámetro ao constructor do ViewHolder é o que empregamos no exemplo anterior.
- Caso b) Xestión do Click sobre un view do conxunto
- Neste caso debemos de rexistrar o evento de Click sobre o view que nos interese.
- O podemos facer na clase ViewHolder ou na clase RecycleViewAdapter_UD04_01_RecycleViewCardView.
1 public class ViewHolder_UD04_01_RecycleViewCardView extends RecyclerView.ViewHolder { 2 3 public ImageView itemImaxe; 4 public TextView itemTexto; 5 6 public ViewHolder_UD04_01_RecycleViewCardView(@NonNull final View itemView) { 7 super(itemView); 8 9 itemImaxe = itemView.findViewById(R.id.imgImaxe_UD04_01_CardLayout); 10 itemTexto = itemView.findViewById(R.id.tvTexto_UD04_01_CardView); 11 12 itemImaxe.setOnClickListener(new View.OnClickListener() { 13 @Override 14 public void onClick(View v) { 15 int posicion = getAdapterPosition(); 16 Toast.makeText(v.getContext(),"Pulsado elemento " + posicion + " da lista.",Toast.LENGTH_SHORT).show(); 17 } 18 }); 19 } 20 }
- Nota: Fixarse que agora soamente responderá ao evento de facer click sobre a imaxe.
Pasando información
- Isto xa está comentado no ImageView.
- Todos view´s dispoñen dunha propiedade Tag asociada na que se pode gardar calquera tipo de información, xa que permite gardar un obxecto de calquera clase.
- Polo tanto podemos empregar dita propiedade para 'asociar' información a un view.
- Nun exemplo real, teríamos unha clase onde gardaríamos os datos de cada elemento da lista. Por exemplo, unha clase Planeta, con datos coma o nome, ruta e nome da imaxe na sd, dimensións, velocidade de rotación,...e moitos máis datos.
- No adaptador do RecycleView teríamos un ArrayList da clase Planeta e non dous arrays separados como temos agora.
- Na lista soamente aparecería a imaxe e nome do planeta, pero nos querremos acceder a todos os seus datos e non soamente aos que aparecen 'visualmente'.
- Imos modificar o exemplo para empregar esta clase Planeta:
- Arquivo: Planeta_UD04_01_RecycleViewCardView.java
1 package cifprodolfoucha.cursoandroid.aprendiendo.UD2.Adaptadores; 2 3 public class Planeta_UD04_01_RecycleViewCardView { 4 5 int id; 6 String nombre; 7 boolean habitable; 8 int fotoId; 9 10 public Planeta_UD04_01_RecycleViewCardView(int id, String nombre, boolean habitable,int fotoId){ 11 this.id = id; 12 this.nombre = nombre; 13 this.habitable = habitable; 14 this.fotoId = fotoId; 15 } 16 17 public int getId() { 18 return id; 19 } 20 21 public String getNombre() { 22 return nombre; 23 } 24 25 public boolean isHabitable() { 26 return habitable; 27 } 28 29 public int getFotoId() { 30 return fotoId; 31 } 32 33 @Override 34 public String toString(){ 35 return "Planeta con id " + id + " e de nome " + nome + (habitable ? " é habitable." : " non é habitable"); 36 } 37 38 }
- Modificamos a clase adaptadora e empregaremos un ArrayList de obxectos pertencentes á clase anterior.
- Estes datos poderían vir dunha base de datos...
- Clase RecycleViewAdapter_UD04_01_RecycleViewCardView
1 package cifprodolfoucha.cursoandroid.aprendiendo.UD2.Adaptadores; 2 3 import android.content.Context; 4 import android.support.annotation.NonNull; 5 import android.support.v7.widget.RecyclerView; 6 import android.view.LayoutInflater; 7 import android.view.View; 8 import android.view.ViewGroup; 9 10 import java.util.ArrayList; 11 12 import cifprodolfoucha.cursoandroid.aprendiendo.R; 13 14 public class RecycleViewAdapter_UD04_01_RecycleViewCardView extends RecyclerView.Adapter { 15 16 private ArrayList<Planeta_UD04_01_RecycleViewCardView>planetas = new ArrayList<Planeta_UD04_01_RecycleViewCardView>(); 17 18 19 public RecycleViewAdapter_UD04_01_RecycleViewCardView(){ 20 21 planetas.add(new Planeta_UD04_01_RecycleViewCardView(1,"MERCURIO",false,R.drawable.mercurio)); 22 planetas.add(new Planeta_UD04_01_RecycleViewCardView(2,"VENUS",false,R.drawable.venus)); 23 planetas.add(new Planeta_UD04_01_RecycleViewCardView(3,"TIERRA",false,R.drawable.tierra)); 24 planetas.add(new Planeta_UD04_01_RecycleViewCardView(4,"JUPITER",false,R.drawable.jupiter)); 25 planetas.add(new Planeta_UD04_01_RecycleViewCardView(5,"SATURNO",false,R.drawable.saturno)); 26 27 } 28 29 @NonNull 30 @Override 31 public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { 32 33 LayoutInflater mInflater = (LayoutInflater) viewGroup.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 34 //View view = (LayoutInflater.from(viewGroup.getContext())) 35 View v = mInflater.inflate(R.layout.card_layout_ud04_01_recycleviewcardview,viewGroup,false); 36 RecyclerView.ViewHolder viewHolder = new ViewHolder_UD04_01_RecycleViewCardView(v); 37 38 return viewHolder; 39 } 40 41 @Override 42 public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { 43 44 ViewHolder_UD04_01_RecycleViewCardView viewHolderMeu = (ViewHolder_UD04_01_RecycleViewCardView) viewHolder; 45 viewHolderMeu.itemImaxe.setImageResource(planetas.get(i).getFotoId()); 46 viewHolderMeu.itemTexto.setText(planetas.get(i).getNombre()); 47 } 48 49 @Override 50 public int getItemCount() { 51 return planetas.size(); 52 } 53 }
- Agora queremos pasar dalgunha forma o obxecto seleccionado (e fixarse que digo obxecto) ao view, de tal forma que cando preme sobre o elemento da lista, poida recuperar a información completa do obxecto.
- Para iso facemos uso do método setTag() e getTag().
Clase RecycleViewAdapter_UD04_01_RecycleViewCardView
1 @Override 2 public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { 3 4 ViewHolder_UD04_01_RecycleViewCardView viewHolderMeu = (ViewHolder_UD04_01_RecycleViewCardView) viewHolder; 5 6 viewHolderMeu.itemView.setTag(planetas.get(i)); 7 viewHolderMeu.itemImaxe.setImageResource(planetas.get(i).getFotoId()); 8 viewHolderMeu.itemTexto.setText(planetas.get(i).getNome()); 9 }
- Nota: Non se pode facer no método 'onCreateViewHolder' xa que o 'int i' non se corresponde có índice do elemento que vai visualizarse.
Clase ViewHolder_UD04_01_RecycleViewCardView
1 public class ViewHolder_UD04_01_RecycleViewCardView extends RecyclerView.ViewHolder { 2 3 public ImageView itemImaxe; 4 public TextView itemTexto; 5 6 public ViewHolder_UD04_01_RecycleViewCardView(@NonNull final View itemView) { 7 super(itemView); 8 9 itemImaxe = itemView.findViewById(R.id.imgImaxe_UD04_01_CardLayout); 10 itemTexto = itemView.findViewById(R.id.tvTexto_UD04_01_CardView); 11 12 itemView.setOnClickListener(new View.OnClickListener() { 13 @Override 14 public void onClick(View v) { 15 Planeta_UD04_01_RecycleViewCardView planetaSeleccionado = (Planeta_UD04_01_RecycleViewCardView) v.getTag(); 16 17 Toast.makeText(v.getContext(),"Pulsado elemento " + getAdapterPosition() + " da lista.\n" + planetaSeleccionado,Toast.LENGTH_SHORT).show(); 18 } 19 }); 20 } 21 }
Engadindo-Borrando-Actualizando elementos
- Se facemos calquera destas operacións teremos que informar ao adaptador que hai cambios para que volva a cargar os elementos da lista.
- Para iso teremos que chamar o método notifyDataSetChanged().
- O malo que ten esta chamada é que é pouco eficiente xa que reconstrúe todos os view´s do RecyclerView.
- Normalmente se chama cando temos moitas operacións ou cambios na estructura de elementos.
- É mais eficiente chamar aos seguintes métodos:
- notifyItemChanged(int)
- notifyItemInserted(int)
- notifyItemRemoved(int)
- notifyItemRangeChanged(int, int)
- notifyItemRangeInserted(int, int)
- notifyItemRangeRemoved(int, int)
- Podedes consultar o que fai cada un neste enlace.
- Seguindo có noso exemplo, imos agregar un botón á activity do RecyclerView (no meu caso engadín un FloatActionButton):
Layout activity_ud04_01_recycle_view_card_view
1 <?xml version="1.0" encoding="utf-8"?>
2 <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto"
4 xmlns:tools="http://schemas.android.com/tools"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent"
7 tools:context=".UD2.Adaptadores.UD04_01_RecycleViewCardView">
8
9 <android.support.v7.widget.RecyclerView
10 android:id="@+id/rvwRecycleView"
11 android:layout_width="match_parent"
12 android:layout_height="match_parent"
13 android:layout_marginTop="24dp"
14 app:layout_constraintBottom_toBottomOf="parent"
15 app:layout_constraintEnd_toEndOf="parent"
16 app:layout_constraintStart_toStartOf="parent"
17 app:layout_constraintTop_toTopOf="parent" />
18
19 <android.support.design.widget.FloatingActionButton
20 android:id="@+id/fabAdd_ud04_01_recyclecardview"
21 android:layout_width="wrap_content"
22 android:layout_height="wrap_content"
23 android:layout_margin="20dp"
24 android:clickable="true"
25 app:layout_constraintBottom_toBottomOf="parent"
26 app:layout_constraintEnd_toEndOf="parent"
27 app:srcCompat="@android:drawable/ic_input_add" />
28 </android.support.constraint.ConstraintLayout>
- Agora os datos van vir dende a Activity e non van estar definidos no clase Adaptadora.
- Para pasar os datos a dita clase, faremos uso do constructor da clase Adaptadora.
Clase RecycleViewAdapter_UD04_01_RecycleViewCardView
1 ..........
2 public class RecycleViewAdapter_UD04_01_RecycleViewCardView extends RecyclerView.Adapter {
3
4 private ArrayList<Planeta_UD04_01_RecycleViewCardView>planetas;
5
6 public RecycleViewAdapter_UD04_01_RecycleViewCardView(ArrayList<Planeta_UD04_01_RecycleViewCardView> planetas){
7 this.planetas = planetas;
8 }
9
10 .......
- Na activity agora é onde teríamos que buscar os datos a unha base de datos, por exemplo, e pasalos á clase Adaptadora no constructor.
Activity UD04_01_RecycleViewCardView
1 package cifprodolfoucha.cursoandroid.aprendiendo.UD2.Adaptadores;
2
3 import android.support.design.widget.FloatingActionButton;
4 import android.support.v7.app.AppCompatActivity;
5 import android.os.Bundle;
6 import android.support.v7.widget.GridLayoutManager;
7 import android.support.v7.widget.LinearLayoutManager;
8 import android.support.v7.widget.RecyclerView;
9 import android.view.View;
10 import android.widget.AdapterView;
11 import android.widget.ListView;
12
13 import java.util.ArrayList;
14
15 import cifprodolfoucha.cursoandroid.aprendiendo.R;
16
17 public class UD04_01_RecycleViewCardView extends AppCompatActivity {
18
19 private RecycleViewAdapter_UD04_01_RecycleViewCardView recycleAdapter;
20
21 private ArrayList<Planeta_UD04_01_RecycleViewCardView>planetas;
22
23 private void inicializarDatosPlanetas(){
24
25 planetas = new ArrayList<>();
26
27 planetas.add(new Planeta_UD04_01_RecycleViewCardView(1,"MERCURIO",false,R.drawable.mercurio));
28 planetas.add(new Planeta_UD04_01_RecycleViewCardView(2,"VENUS",false,R.drawable.venus));
29 planetas.add(new Planeta_UD04_01_RecycleViewCardView(3,"TIERRA",false,R.drawable.tierra));
30 planetas.add(new Planeta_UD04_01_RecycleViewCardView(4,"JUPITER",false,R.drawable.jupiter));
31 planetas.add(new Planeta_UD04_01_RecycleViewCardView(5,"SATURNO",false,R.drawable.saturno));
32
33 }
34 private void inicializarRecycleView(){
35
36 recycleAdapter = new RecycleViewAdapter_UD04_01_RecycleViewCardView(planetas);
37
38 RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
39 RecyclerView recyclerView = findViewById(R.id.rvwRecycleView);
40 recyclerView.setLayoutManager(layoutManager);
41 recyclerView.setAdapter(recycleAdapter);
42
43
44 }
45
46 private void xestionarEventos(){
47
48 FloatingActionButton fab = findViewById(R.id.fabAdd_ud04_01_recyclecardview);
49 fab.setOnClickListener(new View.OnClickListener() {
50 @Override
51 public void onClick(View v) {
52 planetas.add(new Planeta_UD04_01_RecycleViewCardView(6,"URANO",false,R.drawable.ic_menu_camera));
53 recycleAdapter.notifyItemInserted(planetas.size());
54 }
55 });
56
57 }
58
59
60 @Override
61 protected void onCreate(Bundle savedInstanceState) {
62 super.onCreate(savedInstanceState);
63 setContentView(R.layout.activity_ud04_01__recycle_view_card_view);
64
65 inicializarDatosPlanetas();
66 inicializarRecycleView();
67 xestionarEventos();
68
69 }
70 }
- Liña 36: Agora pasamos os datos ao Adaptador mediante o constructor.
- Liña 53: Fixarse como agora, cando engadimos un novo planeta ao ArrayList, chamamos ao método notifyItemInserted, indicando a posición do elemento engadido.
- Probar a cambiar o código e facer que cando se preme o botón se borre o primeiro planeta da lista.
Enlace a la página principal de la UD4
Enlace a la página principal del curso
-- Ángel D. Fernández González e Carlos Carrión Álvarez -- (2018).