Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.
| 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 [2025/10/27 15:25] (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 '' | + | * '' |
| + | * Es manté per //backward compatibility// | ||
| + | * //Widget// recomanat | ||
| Referències: | Referències: | ||
| + | * Article [[Android]] en aquesta wiki. | ||
| + | * [[Android RecyclerView]] en aquesta wiki. | ||
| * [[https:// | * [[https:// | ||
| * [[https:// | * [[https:// | ||
| - | {{tag> #Dam #DamMp08 #DamMp08Uf1 # | + | {{tag> #Dam #DamMp08 #DamMp08Uf1 # |
| - | ===== Perquè és complicada una ListView? | + | ==== Perquè és complicada una ListView? ==== |
| Com veurem ara a l'hora d' | Com veurem ara a l'hora d' | ||
| + | ===== Reciclatge d' | ||
| {{recycling-views.png? | {{recycling-views.png? | ||
| + | ===== Reciclatge d' | ||
| {{recycling-items.jpg? | {{recycling-items.jpg? | ||
| - | 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 '' | + | |
| - | En Android, degut a que necessitem la gestió del reciclatge dels ítems gràfics, ens apareix un element extra anomenat '' | + | {{ listview-adapter.jpg?direct }} |
| - | {{ listview-adapter.jpg? | + | * Tota '' |
| + | * En altres entorns segurament trobaríem una connexió més simple: | ||
| + | * Model de dades (Ex. '' | ||
| + | * El codi de Controlador podria estar en altres objectes de l' | ||
| + | * En Android, degut a que necessitem la gestió del reciclatge dels ítems gràfics, ens **apareix un element extra anomenat '' | ||
| + | ==== Layouts ==== | ||
| Per a cada element (item) de la '' | Per a cada element (item) de la '' | ||
| - | En [[https://gist.github.com/emieza/b918305010be198c037252f402821fef|aquest exemple de ArrayAdapter]] en canvi, hem creat un layout | + | \\ |
| + | |||
| + | ==== Codi taula de rècords ==== | ||
| + | |||
| + | <WRAP info> | ||
| + | Fixeu-vos en què: | ||
| + | * Hi ha els 3 elements: records (model) <-> adapter (ArrayAdapter) <-> listView | ||
| + | * L''' | ||
| + | * Dintre de '' | ||
| + | </WRAP> | ||
| + | |||
| + | <tabbox Kotlin> | ||
| + | |||
| + | <file kotlin MainActivity.kt> | ||
| + | class MainActivity : AppCompatActivity() { | ||
| + | | ||
| + | class Record(var intents: Int, var nom: String) | ||
| + | var records: ArrayList< | ||
| + | |||
| + | // ArrayAdapter serà l' | ||
| + | lateinit var adapter: ArrayAdapter< | ||
| + | |||
| + | override fun onCreate(savedInstanceState: | ||
| + | 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, | ||
| + | insets | ||
| + | } | ||
| + | |||
| + | | ||
| + | records.add(Record(33, | ||
| + | records.add(Record(12, | ||
| + | records.add(Record(42, | ||
| + | |||
| + | // Inicialitzem l'ArrayAdapter | ||
| + | adapter = object : ArrayAdapter< | ||
| + | { | ||
| + | | ||
| + | // getView ens construeix el layout i hi " | ||
| + | var convertView = convertView | ||
| + | if (convertView == null) { | ||
| + | // inicialitzem l' | ||
| + | convertView = getLayoutInflater().inflate(R.layout.list_item, container, false) | ||
| + | } | ||
| + | // pintem imatge | ||
| + | val bitmap = BitmapFactory.decodeStream( assets.open(" | ||
| + | convertView.findViewById< | ||
| + | // " | ||
| + | convertView.findViewById< | ||
| + | convertView.findViewById< | ||
| + | return convertView | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // busquem la ListView i li endollem l' | ||
| + | val lv = findViewById< | ||
| + | lv.setAdapter(adapter) | ||
| + | |||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <tabbox Java> | ||
| + | |||
| + | <file java MainActivity.java> | ||
| + | public class MainActivity extends AppCompatActivity { | ||
| + | |||
| + | // Model: Record (intents=puntuació, | ||
| + | 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< | ||
| + | |||
| + | // ArrayAdapter serà l' | ||
| + | ArrayAdapter< | ||
| + | |||
| + | @Override | ||
| + | protected void onCreate(Bundle savedInstanceState) { | ||
| + | super.onCreate(savedInstanceState); | ||
| + | setContentView(R.layout.activity_main); | ||
| + | |||
| + | // Inicialitzem model | ||
| + | records = new ArrayList< | ||
| + | // Afegim alguns exemples | ||
| + | records.add( new Record(33," | ||
| + | records.add( new Record(12," | ||
| + | records.add( new Record(42," | ||
| + | |||
| + | // Inicialitzem l' | ||
| + | adapter = new ArrayAdapter< | ||
| + | { | ||
| + | @Override | ||
| + | public View getView(int pos, View convertView, | ||
| + | { | ||
| + | // getView ens construeix el layout i hi " | ||
| + | if( convertView==null ) { | ||
| + | // inicialitzem l' | ||
| + | convertView = getLayoutInflater().inflate(R.layout.list_item, | ||
| + | } | ||
| + | // " | ||
| + | ((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 | ||
| + | Button b = (Button) findViewById(R.id.button); | ||
| + | b.setOnClickListener(new View.OnClickListener() { | ||
| + | @Override | ||
| + | public void onClick(View v) { | ||
| + | for (int i=0; | ||
| + | records.add(new Record(100, " | ||
| + | } | ||
| + | // notificar l' | ||
| + | adapter.notifyDataSetChanged(); | ||
| + | } | ||
| + | }); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | </ | ||
| ===== Exercicis ===== | ===== Exercicis ===== | ||
| + | ==== Exercici 1 ==== | ||
| <WRAP todo> | <WRAP todo> | ||
| Implementa el codi d' | Implementa el codi d' | ||
| Línia 39: | Línia 190: | ||
| * Arregla el '' | * Arregla el '' | ||
| * Afegeix al '' | * Afegeix al '' | ||
| - | * Afegeix | + | * Crea un nou // |
| - | * Afegeix un botó amb ID = '' | + | * Transforma el seu layout per defecte a LinearLayout. |
| + | * Afegiex al layout | ||
| + | * Afegeix un botó al //layout// '' | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Exercici 2 ==== | ||
| + | <WRAP todo> | ||
| + | Afegeix un botó **Afegir rècord** que ens ofereixi un '' | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Exercici 3 ==== | ||
| + | <WRAP todo> | ||
| + | Afegeix una imatge als elements de la llista (imatge fixa): | ||
| + | |||
| + | {{ android: | ||
| + | |||
| + | Solució 1: | ||
| + | * Afegeix una '' | ||
| + | * Arranja el //layout// perquè quedi com a la imatge anterior aproximadament. | ||
| + | * Afegeix la carpeta '' | ||
| + | * Afegeix una foto arrossegant-la sobre la vista de projecte d' | ||
| + | * La podràs fer servir amb el codi de l' | ||
| + | val bitmap = BitmapFactory.decodeStream( assets.open(" | ||
| + | convertView.findViewById< | ||
| + | </ | ||
| + | |||
| + | Solució 2: | ||
| + | * Ves a la view de projecte de l' | ||
| + | * Importar una imatge arrossegant-la dins de '' | ||
| + | * Modificar el '' | ||
| + | * Modifica el //layout// del '' | ||
| + | * Pista: pots combinar diversos // | ||
| + | * Afegeix diverses imatges als // | ||
| </ | </ | ||
| + | ==== Exercici 4 ==== | ||
| <WRAP todo> | <WRAP todo> | ||
| Afegeix un botó que ordeni la llista del model, i que refresqui la '' | Afegeix un botó que ordeni la llista del model, i que refresqui la '' | ||