Diferencia entre revisiones de «ListView»

De MediaWiki
Ir a la navegación Ir a la búsqueda
Línea 22: Línea 22:
 
* Todo o visto có Spinner no uso de adaptadores pódese empregar neste view.
 
* Todo o visto có Spinner no uso de adaptadores pódese empregar neste view.
  
−
==Caso Práctico==
+
==Caso Práctico 1==
 
* Partimos que xa temos creado o proxecto inicial como [http://wiki.cifprodolfoucha.es/index.php?title=PDM_Creando_proxecto_base xa indicamos anteriormente].
 
* Partimos que xa temos creado o proxecto inicial como [http://wiki.cifprodolfoucha.es/index.php?title=PDM_Creando_proxecto_base xa indicamos anteriormente].
 
: Se non o temos creado antes, crearemos un novo paquete de nome: '''Adaptadores''' como un subpaquete do teu paquete principal.
 
: Se non o temos creado antes, crearemos un novo paquete de nome: '''Adaptadores''' como un subpaquete do teu paquete principal.
Línea 34: Línea 34:
 
<br />
 
<br />
 
<gallery caption="ListView" widths="350" heights="300px" perrow="2">
 
<gallery caption="ListView" widths="350" heights="300px" perrow="2">
−
Image:Android_2014_U4_03_ListView_01.jpg| Exemplo dunha lista simple, ao premer nun ítem ...
+
Image:PDM_listview_1.jpg| Exemplo dunha lista simple, ao premer nun ítem ...
−
Image:Android_2014_U4_03_ListView_02.jpg| Indícanos que ítem foi seleccionado con un Toast.
+
Image:PDM_listview_2.jpg| Indícanos que ítem foi seleccionado con un Toast.
 
</gallery>
 
</gallery>
  
Línea 130: Línea 130:
 
*'''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.
 
*'''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.
  
 +
 +
<br />
 
==ListView usando un recurso XML ou un array dinámico==
 
==ListView usando un recurso XML ou un array dinámico==
 
*Neste caso funciona igual que o visto no Spinner que fai uso dun adaptador.
 
*Neste caso funciona igual que o visto no Spinner que fai uso dun adaptador.
  
  
 +
<br />
 +
==Caso Práctico 2==
 +
* Partimos que xa temos creado o proxecto inicial como [http://wiki.cifprodolfoucha.es/index.php?title=PDM_Creando_proxecto_base xa indicamos anteriormente].
 +
: Se non o temos creado antes, crearemos un novo paquete de nome: '''Adaptadores''' como un subpaquete do teu paquete principal.
 +
 +
 +
<br />
 +
* 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 [http://wiki.cifprodolfoucha.es/index.php?title=PDM_Creando_proxecto_base 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: <b>android:choiceMode="multipleChoice"</b>
 +
:* Ou ben ter unha referencia ao ListView e cambia dito atributo por programación: <b>refLista.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);</b>
 +
 +
 +
* O layout que imos utilizar é: [https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/res/res/layout/simple_list_item_checked.xml R.layout.simple_list_item_checked] que podemos comprobar que está formado por un CheckedTextView.
 +
 +
 +
* O máis complicado será, 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:
 +
::::<syntaxhighlight lang="java" line highlight="">
 +
            private ArrayList<String>datos = new ArrayList<>();
 +
            ...............
 +
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
 +
                // TODO Auto-generated method stub
 +
                CheckedTextView c = (CheckedTextView)view;
 +
                if (c.isChecked()){
 +
                    datos.add(c.getText().toString());
 +
                }
 +
                else {
 +
                    datos.remove(c.getText().toString());
 +
                }
 +
          }
 +
</syntaxhighlight>
 +
 +
:* '''Opción b)'''
 +
::: Facer uso da [https://developer.android.com/reference/android/util/SparseBooleanArray clase SparseBooleanArray] e do [https://developer.android.com/reference/android/widget/AbsListView.html#getCheckedItemPositions() método getCheckedItemPositions] o cal devolve un obxecto da clase SparseBooleanArray coas posicións dos elementos seleccionados.
 +
::: Para facer iso disto temos:
 +
::::<syntaxhighlight lang="java" line highlight="">
 +
                SparseBooleanArray elems = referenciaLista.getCheckedItemPositions();
 +
                for(int cont=0; cont < referenciaLista.getCount();cont++){
 +
                    if (elems.get(cont)){
 +
                      // Está seleccionado
 +
                    }
 +
                }
 +
 +
</syntaxhighlight>
 +
 +
 +
 +
 +
<br />
 +
<gallery caption="ListView" widths="350" heights="300px" perrow="2">
 +
Image:PDM_listview_3.jpg| ListView cun layout que permite selección múltiple.
 +
Image:PDM_listview_4.jpg| Ao seleccionar un elemento, se está chequeado, aparecerá nun texto na parte baixa.
 +
</gallery>
 +
 +
 +
 +
<br />
 +
===XML do Layout===
 +
<syntaxhighlight lang="xml" line enclose="div" highlight="28" >
 +
<?xml version="1.0" encoding="utf-8"?>
 +
<android.support.constraint.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_02_ListViews">
  
 +
    <LinearLayout
 +
        android:layout_width="0dp"
 +
        android:layout_height="149dp"
 +
        android:layout_marginEnd="32dp"
 +
        android:layout_marginStart="32dp"
 +
        android:layout_marginTop="8dp"
 +
        android:orientation="vertical"
 +
        app:layout_constraintEnd_toEndOf="parent"
 +
        app:layout_constraintStart_toStartOf="parent"
 +
        app:layout_constraintTop_toTopOf="parent">
 +
 +
        <ListView
 +
            android:id="@+id/lvCoches_UD04_02_ListViews"
 +
            android:layout_width="match_parent"
 +
            android:layout_height="0dp"
 +
            android:layout_marginEnd="8dp"
 +
            android:layout_marginStart="8dp"
 +
            android:layout_marginTop="8dp"
 +
            android:layout_weight="1"
 +
            android:choiceMode="multipleChoice">
 +
 +
        </ListView>
 +
    </LinearLayout>
 +
 +
    <TextView
 +
        android:id="@+id/tvSeleccionados_UD04_02_ListViews"
 +
        android:layout_width="0dp"
 +
        android:layout_height="wrap_content"
 +
        android:layout_marginBottom="8dp"
 +
        android:layout_marginEnd="8dp"
 +
        android:layout_marginStart="8dp"
 +
        android:textSize="24sp"
 +
        app:layout_constraintBottom_toBottomOf="parent"
 +
        app:layout_constraintEnd_toEndOf="parent"
 +
        app:layout_constraintStart_toStartOf="parent"
 +
        tools:text="Elementos seleccionados" />
 +
 +
</android.support.constraint.ConstraintLayout>
 +
</syntaxhighlight>
 +
 +
 +
 +
<br />
 +
===Código da Activity===
 +
<syntaxhighlight lang="java" line highlight="">
 +
package es.cursoandroid.cifprodolfoucha.aprendiendo.Adaptadores;
 +
 +
import android.app.Activity;
 +
import android.os.Bundle;
 +
import android.text.Html;
 +
import android.util.SparseBooleanArray;
 +
import android.view.View;
 +
import android.widget.AdapterView;
 +
import android.widget.ArrayAdapter;
 +
import android.widget.CheckedTextView;
 +
import android.widget.ListView;
 +
import android.widget.TextView;
 +
import android.widget.Toast;
 +
 +
import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
 +
 +
public class UD04_02_ListViews extends Activity {
 +
 +
    private void cargarListas(){
 +
        //Fonte de datos
 +
        String[] coches = new String[] { "FORD", "OPEL", "SEAT","CITROEN","VOLKSWAGEN","ONDA" };
 +
 +
        //Enlace do adaptador coa fonte de datos
 +
        ArrayAdapter<String> adaptador = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_checked, coches);
 +
 +
        ListView lvCoches = findViewById(R.id.lvCoches_UD04_02_ListViews);
 +
        //Enlace do adaptador co ListView
 +
        lvCoches.setAdapter(adaptador);
 +
    }
 +
 +
    private void xestionarEventos(){
 +
 +
        final ListView lvCoches = findViewById(R.id.lvCoches_UD04_02_ListViews);
 +
 +
        //Escoitador
 +
        lvCoches.setOnItemClickListener(new AdapterView.OnItemClickListener() {
 +
 +
            @Override
 +
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
 +
                // TODO Auto-generated method stub
 +
                CheckedTextView c = (CheckedTextView)view;
 +
                Toast.makeText(getApplicationContext(),c.getText(),Toast.LENGTH_LONG).show();
 +
 +
                TextView mensaxe = findViewById(R.id.tvSeleccionados_UD04_02_ListViews);
 +
                mensaxe.setText("");
 +
                SparseBooleanArray elems = lvCoches.getCheckedItemPositions();
 +
                for(int cont=0; cont < lvCoches.getCount();cont++){
 +
                    if (elems.get(cont)){
 +
                      mensaxe.append(lvCoches.getItemAtPosition(cont).toString()+ Html.fromHtml("<br />"));
 +
                    }
 +
                }
 +
 +
            }
 +
        });
 +
    }
 +
 +
 +
    @Override
 +
    protected void onCreate(Bundle savedInstanceState) {
 +
        super.onCreate(savedInstanceState);
 +
        setContentView(R.layout.activity_ud04_02__list_views);
 +
 +
        cargarListas();
 +
        xestionarEventos();
 +
    }
 +
}
 +
</syntaxhighlight>
  
  

Revisión del 21:21 12 oct 2018

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>



O código Java da aplicación

  • 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

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 máis complicado será, 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 -- (2015).