ListView

De MediaWiki
Saltar a: navegación, buscar

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.

Listview.png

  • 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'.
  • Todo o visto có Spinner no uso de adaptadores pódese empregar neste view.

Caso Práctico 1

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_01_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.




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

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);



  • 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. }




-- Ángel D. Fernández González e Carlos Carrión Álvarez -- (2018).