bytes.cat

La wiki d'FP d'informàtica

Eines de l'usuari

Eines del lloc


android_listview

Diferències

Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.

Enllaç a la visualització de la comparació

Ambdós costats versió prèvia Revisió prèvia
Següent revisió
Revisió prèvia
android_listview [2021/10/15 15:23]
enrique_mieza_sanchez [MVC + Adapter]
android_listview [2023/12/18 22:48] (actual)
enric_mieza_sanchez
Línia 1: Línia 1:
 +~~REVEAL~~
 +
 ====== Utilitzant ListView a Android ====== ====== Utilitzant ListView a Android ======
 +Aquest article segueix del principal [[Android]] en aquesta wiki.
  
-Una ''ListView'' és una //widget// obsolet però que ha tingut molta utilització i es manté per //backward compatibility//Com que el seu substitut actual, la ''RecycleView'' és una mica complicada d'utilitzar, farem primer aquest exemple amb la ''ListView'' antiga per entendre el funcionament.+  * ''ListView'' és un //widget// obsolet
 +  * Es manté per //backward compatibility//. 
 +  * //Widget// recomanat actual: [[Android RecyclerView]] (però més complicat d'utilitzar).
  
 Referències: Referències:
 +  * Article [[Android]] en aquesta wiki.
 +  * [[Android RecyclerView]] en aquesta wiki.
   * [[https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView|Tutorial d'utilització de ListView d'Android]]   * [[https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView|Tutorial d'utilització de ListView d'Android]]
   * [[https://gist.github.com/emieza/b918305010be198c037252f402821fef|Codi d'exemple més simple d'utilització d'una ListView]]   * [[https://gist.github.com/emieza/b918305010be198c037252f402821fef|Codi d'exemple més simple d'utilització d'una ListView]]
  
-{{tag> #Dam #DamMp08 #DamMp08Uf1 #DamMp08Uf01 }}+{{tag> #Dam #DamMp08 #DamMp08Uf1 #DamMp08Uf01 android MVC java mobile}}
  
-===== Perquè és complicada una ListView? =====+==== Perquè és complicada una ListView? ====
 Com veurem ara a l'hora d'implementar-ho, la ''ListView'' resulta una mica més complicada del què ens esperaríem. Això es deu a la particularitat dels dispositius mòbils de la seva escassa RAM. No podem, doncs, implementar una llista amb gran quantitat d'entrades que poden contenir pesants elements multimèdia com fotos d'alta resolució, i que es carreguin totes a la RAM directament. Ens **cal uns tipus de ''Views'' que carreguin només les dades que s'estan visualitzant, i que generin nous ítems només quan l'usuari faci el //scroll//**. Com veurem ara a l'hora d'implementar-ho, la ''ListView'' resulta una mica més complicada del què ens esperaríem. Això es deu a la particularitat dels dispositius mòbils de la seva escassa RAM. No podem, doncs, implementar una llista amb gran quantitat d'entrades que poden contenir pesants elements multimèdia com fotos d'alta resolució, i que es carreguin totes a la RAM directament. Ens **cal uns tipus de ''Views'' que carreguin només les dades que s'estan visualitzant, i que generin nous ítems només quan l'usuari faci el //scroll//**.
  
 +===== Reciclatge d'elements gràfics =====
 {{recycling-views.png?direct}} {{recycling-views.png?direct}}
  
 +===== Reciclatge d'elements gràfics (2) =====
 {{recycling-items.jpg?direct}} {{recycling-items.jpg?direct}}
  
-Com podem veure a la imatge, a més, el sistema farà un **reciclat dels ítems que ha generat prèviament i que ja no estan visibles**, estalviant RAM de forma global.+Com podem veure a la imatge, el sistema farà un **reciclat dels ítems que ha generat prèviament i que ja no estan visibles**, estalviant RAM de forma global.
  
 \\ \\
  
-===== MVC Adapter ===== +===== MVC ampliat i Adapter =====
-Tota ''View'' te la intenció de seguir un paradigma Model - Vista - Controlador. En altres entorns segurament trobaríem el Model de dades, per exemple, un ''ArrayList'', connectat directament a la ''ListView'', i el codi de Controlador podria estar en altres objectes de l'aplicació (com la ''Activity'') o en una classe derivada de la ''ListView''.+
  
-En Android, degut a que necessitem la gestió del reciclatge dels ítems gràfics, ens apareix un element extra anomenat ''Adapter''. Aquest és l'element que coneix la ''View'' i el nostre Model i que ha de saber com reciclar els ítems per a l'estalvi de RAM.+{{ listview-adapter.jpg?direct }}
  
-{{ listview-adapter.jpg?direct&500 }}+  * Tota ''View'' intenta seguir un paradigma Model Vista - Controlador. 
 +  * En altres entorns segurament trobaríem una connexió més simple: 
 +    * Model de dades (Ex. ''ArrayList'') connectat directament a la ''ListView''
 +    * El codi de Controlador podria estar en altres objectes de l'aplicació (com la ''Activity'') o en una classe derivada de la ''ListView''
 +  * En Android, degut a que necessitem la gestió del reciclatge dels ítems gràfics, ens **apareix un element extra anomenat ''Adapter''**. Aquest és l'element que coneix la ''View'' i el nostre Model i que ha de saber com **reciclar els ítems per a l'estalvi de RAM**.
  
 +==== Layouts ====
 Per a cada element (item) de la ''ListView'' es necessita un //layout// personalitzat. El pots crear tu mateix, o simplement adoptar uns //layouts// prefabricats per als items. Al [[https://developer.android.com/reference/android/R.layout|arxiu de recursos android.R.layout]] trobaràs alguns com per exemple [[https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView#using-a-basic-arrayadapter|android.R.layout.simple_list_item_1]] que et pot estalviar feina per als casos més habituals. Per a cada element (item) de la ''ListView'' es necessita un //layout// personalitzat. El pots crear tu mateix, o simplement adoptar uns //layouts// prefabricats per als items. Al [[https://developer.android.com/reference/android/R.layout|arxiu de recursos android.R.layout]] trobaràs alguns com per exemple [[https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView#using-a-basic-arrayadapter|android.R.layout.simple_list_item_1]] que et pot estalviar feina per als casos més habituals.
  
-En [[https://gist.github.com/emieza/b918305010be198c037252f402821fef|aquest exemple de ArrayAdapter]] en canvi, hem creat un layout personalitzat per a la nostra taula.+\\ 
 + 
 +===== Exemple ArrayList simplificat ===== 
 + 
 +  * Referència: [[https://gist.github.com/emieza/b918305010be198c037252f402821fef|codi d'exemple amb ArrayAdapter]]
 +  * Exemple d'una taula de rècords amb nom del jugador i intents. 
 +  * Utilitza un ''list_item'' personalitzat
 +  * No creem una classe derivada de ''ArrayAdapter'': simplement instanciem un de genèric (línia 43) i sobreescrivim el mètode ''getView''
 + 
 +==== Codi taula de rècords ==== 
 +<file java> 
 +package com.example.listilla; 
 + 
 +import android.os.Bundle; 
 +import android.view.View; 
 +import android.view.ViewGroup; 
 +import android.widget.*; 
 + 
 +import androidx.appcompat.app.AppCompatActivity; 
 + 
 +import java.util.ArrayList; 
 + 
 +public class MainActivity extends AppCompatActivity { 
 + 
 +    // Model: Record (intents=puntuació, nom) 
 +    class Record { 
 +        public int intents; 
 +        public String nom; 
 + 
 +        public Record(int _intents, String _nom ) { 
 +            intents = _intents; 
 +            nom = _nom; 
 +        } 
 +    } 
 +    // Model = Taula de records: utilitzem ArrayList 
 +    ArrayList<Record> records; 
 + 
 +    // ArrayAdapter serà l'intermediari amb la ListView 
 +    ArrayAdapter<Record> adapter; 
 + 
 +    @Override 
 +    protected void onCreate(Bundle savedInstanceState) { 
 +        super.onCreate(savedInstanceState); 
 +        setContentView(R.layout.activity_main); 
 + 
 +        // Inicialitzem model 
 +        records = new ArrayList<Record>(); 
 +        // Afegim alguns exemples 
 +        records.add( new Record(33,"Manolo") ); 
 +        records.add( new Record(12,"Pepe") ); 
 +        records.add( new Record(42,"Laura") ); 
 + 
 +        // Inicialitzem l'ArrayAdapter amb el layout pertinent 
 +        adapter = new ArrayAdapter<Record>( this, R.layout.list_item, records ) 
 +        { 
 +            @Override 
 +            public View getView(int pos, View convertView, ViewGroup container) 
 +            { 
 +                // getView ens construeix el layout i hi "pinta" els valors de l'element en la posició pos 
 +                if( convertView==null ) { 
 +                    // inicialitzem l'element la View amb el seu layout 
 +                    convertView = getLayoutInflater().inflate(R.layout.list_item, container, false); 
 +                } 
 +                // "Pintem" valors (també quan es refresca) 
 +                ((TextView) convertView.findViewById(R.id.nom)).setText(getItem(pos).nom); 
 +                ((TextView) convertView.findViewById(R.id.intents)).setText(Integer.toString(getItem(pos).intents)); 
 +                return convertView; 
 +            } 
 + 
 +        }; 
 + 
 +        // busquem la ListView i li endollem el ArrayAdapter 
 +        ListView lv = (ListView) findViewById(R.id.recordsView); 
 +        lv.setAdapter(adapter); 
 + 
 +        // botó per afegir entrades a la ListView 
 +        Button b = (Button) findViewById(R.id.button); 
 +        b.setOnClickListener(new View.OnClickListener() { 
 +            @Override 
 +            public void onClick(View v) { 
 +                for (int i=0;i<3;i++) { 
 +                    records.add(new Record(100, "Anonymous")); 
 +                } 
 +                // notificar l'adapter dels canvis al model 
 +                adapter.notifyDataSetChanged(); 
 +            } 
 +        }); 
 +    } 
 +
 + 
 +</file> 
  
 ===== Exercicis ===== ===== Exercicis =====
  
 +==== Exercici 1 ====
 <WRAP todo> <WRAP todo>
 Implementa el codi d'exemple en un nou projecte anomenat "Listilla". Implementa el codi d'exemple en un nou projecte anomenat "Listilla".
Línia 39: Línia 144:
   * Arregla el ''package'' perquè concordi amb el teu projecte.   * Arregla el ''package'' perquè concordi amb el teu projecte.
   * Afegeix al ''activity_main.xml'' una ''ListView'' anomenada ''recordsView''.   * Afegeix al ''activity_main.xml'' una ''ListView'' anomenada ''recordsView''.
-  * Afegeix un nou //layout// lineal dins la ''ListView'' anomenat ''list_item''Aquest contindrà 2 ''TextView'' amb IDs ''nom'' i ''intents''+  * Crea un nou //layout// amb el nom ''list_item.xml'' que serà el //placeholder// per cada element de la llistaPots crear-ho amb <code>File -> New -> Layout Resource File</code> 
-  * Afegeix un botó amb ID = ''button''. Servirà per afegir ítems al ''ListView'' i comprovar el //scroll//.+    * Transforma el seu layout per defecte a LinearLayout. 
 +    * Afegiex 2 ''TextView'' amb IDs ''nom'' i ''intents''
 +  * Afegeix un botó al //layout// ''activity_main.xml'' amb ID = ''button''. Servirà per afegir ítems al ''ListView'' i comprovar el //scroll// del ''ListView''
 +</WRAP> 
 + 
 + 
 +==== Exercici 2 ==== 
 +<WRAP todo> 
 +Randomitza la generació d'entrades a la taula, generant nº d'intents variats i noms i cognoms mesclant-los de dues llistes d'uns 15 o 20 elements. 
 +</WRAP> 
 + 
 + 
 +==== Exercici 3 ==== 
 +<WRAP todo> 
 +Afegeix una imatge als elements de la llista (imatge fixa). Per fer-ho hauràs de: 
 +  * Ves a la view de projecte de l'Android Studio. Visualitza la carepta <code>res -> drawable</code> 
 +  * Importar una imatge arrossegant-la dins de ''Drawable''
 +  * Modificar el ''list_item.xml'' i afegir-hi una ''ImageView'' amb la imatge anterior. 
 +  * Modifica el //layout// del ''list_item'' perquè et quedi com la imatge suggerida adjunta. 
 +    * Pista: pots combinar diversos //LinearLayout// horitzontals i verticals per aconseguir el resultat desitjat. 
 +  * Afegeix diverses imatges als //resources// i aleatoritza l'assignació d'imatges a cada element ''Record''
 + 
 +{{ android:listilla1.png?200 }}
 </WRAP> </WRAP>
  
  
 +==== Exercici 4 ====
 <WRAP todo> <WRAP todo>
 Afegeix un botó que ordeni la llista del model, i que refresqui la ''ListView''. Afegeix un botó que ordeni la llista del model, i que refresqui la ''ListView''.
android_listview.1634311383.txt.gz · Darrera modificació: 2021/10/15 15:23 per enrique_mieza_sanchez