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 16:07]
enrique_mieza_sanchez
android_listview [2025/10/27 15:25] (actual)
enric_mieza_sanchez
Línia 2: Línia 2:
  
 ====== Utilitzant ListView a Android ====== ====== Utilitzant ListView a Android ======
 +Aquest article segueix del principal [[Android]] en aquesta wiki.
  
   * ''ListView'' és un //widget// obsolet.   * ''ListView'' és un //widget// obsolet.
   * Es manté per //backward compatibility//.   * Es manté per //backward compatibility//.
-  * Substitut actual: ''RecycleView'' més complicat d'utilitzar+  * //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? ====
Línia 26: Línia 29:
 \\ \\
  
-===== Paradigma MVC ampliat ===== +===== 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'', 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. +
- +
-===== Utilitzant Adapter =====+
  
 {{ listview-adapter.jpg?direct }} {{ listview-adapter.jpg?direct }}
 +
 +  * 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 ==== ==== Layouts ====
Línia 40: Línia 44:
 \\ \\
  
-===== Exemple ArrayList simplificat ===== +==== Codi taula de rècords ====
-Podeu veure en [[https://gist.github.com/emieza/b918305010be198c037252f402821fef|aquest exemple de ArrayAdapter]] com utilitzar un ''list_item'' personalitzat. Fixeu-vos en què no creem una classe derivada de ''ArrayAdapter'', sinó que simplement instanciem un de genèric (línia 43) i sobreescrivim el mètode ''getView''.+
  
-En aquest exemple estem fent una taula de rècords on enregistrem el nom del jugador i el nombre d'intents que ha fet per resoldre un joc d'endevinar el número.+<WRAP info> 
 +Fixeu-vos en què: 
 +  * Hi ha els 3 elements: records (model) <-> adapter (ArrayAdapter) <-> listView 
 +  * L'''adapter'' es pot crear com una classe derivada, o bé un **objecte particularitzat**. En aquest cas és la 2a opció (objecte particularitzat "inline"). 
 +  * Dintre de ''adapter.getView'' es realitza el **reciclatge**: si ens ve un objecte ''null'', l'inicialitzem amb el ''LayoutInflater''. Si no és ''null'', el reciclem sobreescrivint i modificant les dades. 
 +</WRAP>
  
-==== Codi taula de rècords ==== +<tabbox Kotlin>
-<sxh java> +
-package com.example.listilla;+
  
-import android.os.Bundle; +<file kotlin MainActivity.kt> 
-import android.view.View; +class MainActivity : AppCompatActivity() { 
-import android.view.ViewGroup; +    // Model: ArrayList de Record (intents=puntuació, nom) 
-import android.widget.*;+    class Record(var intents: Int, var nom: String) 
 +    var records: ArrayList<Record> = ArrayList<Record>()
  
-import androidx.appcompat.app.AppCompatActivity;+    // ArrayAdapter serà l'intermediari amb la ListView 
 +    lateinit var adapter: ArrayAdapter<Record> 
 + 
 +    override fun onCreate(savedInstanceState: Bundle?) { 
 +        super.onCreate(savedInstanceState) 
 +        enableEdgeToEdge() 
 +        setContentView(R.layout.activity_main) 
 +        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> 
 +            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) 
 +            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) 
 +            insets 
 +        } 
 + 
 +        // Afegim alguns exemples 
 +        records.add(Record(33, "Manolo")) 
 +        records.add(Record(12, "Pepe")) 
 +        records.add(Record(42, "Laura")) 
 + 
 +        // Inicialitzem l'ArrayAdapter amb el layout pertinent 
 +        adapter = object : ArrayAdapter<Record>(this,R.layout.list_item,records) 
 +        { 
 +             override fun getView(pos: Int, convertView: View?, container: ViewGroup): View { 
 +                // getView ens construeix el layout i hi "pinta" els valors de l'element en la posició pos 
 +                var convertView = convertView 
 +                if (convertView == null) { 
 +                    // inicialitzem l'element la View amb el seu layout 
 +                    convertView = getLayoutInflater().inflate(R.layout.list_item, container, false) 
 +                } 
 +                // pintem imatge 
 +                val bitmap = BitmapFactory.decodeStream( assets.open("ieti_logo.png") ) 
 +                convertView.findViewById<ImageView>(R.id.imageView).setImageBitmap( bitmap ) 
 +                // "Pintem" valors (quan es refresca) 
 +                convertView.findViewById<TextView>(R.id.nom).text = getItem(pos)?.nom 
 +                convertView.findViewById<TextView>(R.id.intents).text = getItem(pos)?.intents.toString() 
 +                return convertView 
 +            } 
 +        } 
 + 
 +        // busquem la ListView i li endollem l'ArrayAdapter 
 +        val lv = findViewById<ListView>(R.id.recordsView) 
 +        lv.setAdapter(adapter) 
 + 
 +    } 
 +
 +</file>
  
-import java.util.ArrayList;+<tabbox Java>
  
 +<file java MainActivity.java>
 public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
  
Línia 116: Línia 168:
             @Override             @Override
             public void onClick(View v) {             public void onClick(View v) {
-                for (int i=0;i<500;i++) {+                for (int i=0;i<3;i++) {
                     records.add(new Record(100, "Anonymous"));                     records.add(new Record(100, "Anonymous"));
                 }                 }
Línia 126: Línia 178:
 } }
  
-</sxh+</file
 +</tabbox>
  
 ===== 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 137: Línia 190:
   * 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 al layout 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> </WRAP>
  
 +
 +==== Exercici 2 ====
 <WRAP todo> <WRAP todo>
-Randomitza la generació d'entrades a la taula, generant nº d'intents variats i noms trets d'una llista d'uns 15 o 20 elements.+Afegeix un botó **Afegir rècord** que ens ofereixi un ''Dialog'' per entrar nom i rècord.
 </WRAP> </WRAP>
  
 +
 +==== Exercici 3 ====
 +<WRAP todo>
 +Afegeix una imatge als elements de la llista (imatge fixa):
 +
 +{{ android:listilla1.png?200 }}
 +
 +Solució 1:
 +  * Afegeix una ''ImageView'' amnb ID "imageView" al ''list_item.xml''.
 +  * Arranja el //layout// perquè quedi com a la imatge anterior aproximadament.
 +  * Afegeix la carpeta ''app/src/main/**assets**'' al projecte.
 +  * Afegeix una foto arrossegant-la sobre la vista de projecte d'Android Studio.
 +  * La podràs fer servir amb el codi de l'exemple:<code kotlin>
 +val bitmap = BitmapFactory.decodeStream( assets.open("ieti_logo.png") )
 +convertView.findViewById<ImageView>(R.id.imageView).setImageBitmap( bitmap )
 +</code>
 +
 +Solució 2:
 +  * 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''.
 +
 +</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.1634314066.txt.gz · Darrera modificació: 2021/10/15 16:07 per enrique_mieza_sanchez