Diferencia entre revisiones de «Spinner a través de adaptador»
Ir a la navegación
Ir a la búsqueda
| Línea 1: | Línea 1: | ||
==Introdución== | ==Introdución== | ||
| + | |||
| + | * Máis información en [https://developer.android.com/reference/android/widget/Spinner https://developer.android.com/reference/android/widget/Spinner] | ||
| + | |||
| + | <br /> | ||
*Xa vimos na unidade 2 como crear un [[Spinner]], pero o enlace dos datos co Spinner facíase a través dun atributo XML na definición do Spinner no Layout: '''android:entries'''. | *Xa vimos na unidade 2 como crear un [[Spinner]], pero o enlace dos datos co Spinner facíase a través dun atributo XML na definición do Spinner no Layout: '''android:entries'''. | ||
*Agora imos facer o mesmo pero usando un adaptador. | *Agora imos facer o mesmo pero usando un adaptador. | ||
| Línea 68: | Línea 72: | ||
adapter.setNotifyOnChange(true); | adapter.setNotifyOnChange(true); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | |||
| + | <br /> | ||
| + | * A xestión de eventos neste control inclúe a interface que controla cando un elemento da lista é premido. É a [https://developer.android.com/reference/android/widget/AdapterView.OnItemSelectedListener interface OnItemSelectedListener] e se rexistra có [https://developer.android.com/reference/android/widget/AdapterView.html#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener) método setOnItemClickListener (AdapterView.OnItemClickListener l)] do Spinner. | ||
| + | : Ao facelo, deberá implementarse estes dous método: | ||
| + | :<syntaxhighlight lang="java" line highlight=""> | ||
| + | @Override | ||
| + | public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { | ||
| + | |||
| + | } | ||
| + | |||
| + | @Override | ||
| + | public void onNothingSelected(AdapterView<?> parent) { | ||
| + | |||
| + | } | ||
| + | |||
| + | </syntaxhighlight> | ||
| + | |||
| + | :: O segundo método se chama cando non se selecciona ningún elemento e desaparece a lista. | ||
| + | :: O primeiro cando se selecciona un elemento da lista. | ||
| + | :: Leva como parámetros: | ||
| + | ::* O adaptador asociado á lista. | ||
| + | ::* O view que foi seleccionado (lembrar que cando se crea o adaptador se establece un layout para cada compoñente da lista) | ||
| + | ::* A posición do elemento seleccionado na lista (empeza en 0) | ||
| + | ::* Un identificador para a fila que foi seleccionada. | ||
==Caso práctico== | ==Caso práctico== | ||
Revisión del 15:57 11 oct 2018
Sumario
Introdución
- Máis información en https://developer.android.com/reference/android/widget/Spinner
- Xa vimos na unidade 2 como crear un Spinner, pero o enlace dos datos co Spinner facíase a través dun atributo XML na definición do Spinner no Layout: android:entries.
- Agora imos facer o mesmo pero usando un adaptador.
- Colleremos os datos dende un array no código e logo dende un recurso XML.
- Se queremos cargar ditos recursos por programación:
- Deberemos facer uso dun obxecto da clase ArrayAdapter. Este obxecto serve coma ponte entre os datos e o spinner. A modificacións dos datos da lista sempre se fai no adaptador asociado á mesma e nunca sobre o spinner. Engadir, borrar, modificar, limpar,...todas esas operacións se teñen que facer sobre o adaptador.
- Deberemos de obter os datos para encher o spinner. Estes datos poden vir dun array gardado en /res/ e para referencialo teremos que facer uso do método getResources().
- Deberemos de establecer o aspecto (layout) que terá cada un dos 'views' que conforman cada elemento da lista (si, cada elemento da lista ten que ser un view :) )
- Deberemos establecer o aspecto (layout) do spinner cando prememos na lista e se despregan todos os elementos.
- Para crear un ArrayAdapter podemos seguir este código:
1 Spinner lista = findViewById(R.id.id_spinner);
2
3 ArrayAdapter<CharSequence>adaptador = ArrayAdapter.createFromResource(this,R.array.planetas_UD02_01_spinner,android.R.layout.simple_list_item_1);
4 adaptador.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
5 lista.setAdapter(adaptador);
- Na liña 3 creamos un ArrayAdapter facendo uso do método createFromResource. Dito método recibe como parámetros:
- O contexto
- Os datos do ArrayAdapter, que neste caso veñen dun recurso xa creado previamente noutro exercicio.
- O Layout que vai ter asociado cada view (elemento da lista, que dependendo do layout serán views como TextViews).
- Os layout que se poden empregar se poden consultar en http://wiki.cifprodolfoucha.es/index.php?title=Spinner#Caso_pr.C3.A1ctico
- O código fonte de cada layout se pode consultar en https://github.com/aosp-mirror/platform_frameworks_base/tree/master/core/res/res/layout
- Na liña 4, establecemos o layout que vai ter o spinner cando prememos sobre el e aparezan todos os elementos da lista. Podemos consultar o código fonte de dito layout.
- Na liña 5 asociamos o ArrayAdapter ao Spinner.
- Podemos facer o mesmo desta outra forma:
1 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,getResources().getStringArray(R.array.planetas_UD02_01_spinner));
- Para referenciar o array teríamos que facer uso da clase getResource() e obter o tipo correspondente (array).
- O ArrayAdapter está 'cheo' de métodos para engadir, borrar e modificar elementos da lista.
- Por exemplo:
- add(T object): Engade un elemento á lista de elementos.
- addAll(Collection<? extends T> collection): Engade unha colección.
- getCount(): Devolve o número de elementos da lista.
- getItem(int position): Devolve o elemento da lista en base a súa posición (empeza en 0)
- insert(T object, int index) : Engade un elemento na posición indicada.
- remove(T object): Elimina un elemento da lista.
- clear(): Borra todos os elementos da lista.
- Importante: Calquera modificación que se faga sobre os elementos da lista facendo uso do adaptador, leva consigo a 'obriga' de informar ao view dos cambios para que os reflicta. Isto se consigo chamando ao método setNotifyOnChange(boolean notifyOnChange), cun valor true no parámetro.
- Por exemplo, o código anterior se podería cambiar por:
1 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item); 2 adapter.addAll(getResources().getStringArray(R.array.planetas_UD02_01_spinner)); 3 adapter.setNotifyOnChange(true);
- A xestión de eventos neste control inclúe a interface que controla cando un elemento da lista é premido. É a interface OnItemSelectedListener e se rexistra có método setOnItemClickListener (AdapterView.OnItemClickListener l) do Spinner.
- Ao facelo, deberá implementarse estes dous método:
1 @Override 2 public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 3 4 } 5 6 @Override 7 public void onNothingSelected(AdapterView<?> parent) { 8 9 }
- O segundo método se chama cando non se selecciona ningún elemento e desaparece a lista.
- O primeiro cando se selecciona un elemento da lista.
- Leva como parámetros:
- O adaptador asociado á lista.
- O view que foi seleccionado (lembrar que cando se crea o adaptador se establece un layout para cada compoñente da lista)
- A posición do elemento seleccionado na lista (empeza en 0)
- Un identificador para a fila que foi seleccionada.
Caso práctico
- Crear o proxecto: U4_02_SpinnerAdapter.
- Aplicación Diálogos
- Cada ítem do Spinner é tratado como unha View, neste caso de tipo TextView.
O XML do layout
- Observar como a vista Spinner non ten a entrada android:entries.
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="wrap_content"
9 android:layout_height="wrap_content"
10 android:text="Selecciona unha froita" />
11
12 <Spinner
13 android:id="@+id/spin_froitas"
14 android:layout_width="wrap_content"
15 android:layout_height="wrap_content" />
16
17 </LinearLayout>
Usando un array estático en Java
- Ao final do código explícase como se enlaza a fonte de datos co adaptador e este co spinner.
- Observar as liñas marcadas.
1 package com.example.u4_02_spinneradapter;
2
3 import android.app.Activity;
4 import android.os.Bundle;
5 import android.view.Menu;
6 import android.view.View;
7 import android.widget.TextView;
8 import android.widget.AdapterView;
9 import android.widget.AdapterView.OnItemSelectedListener;
10 import android.widget.ArrayAdapter;
11 import android.widget.Spinner;
12 import android.widget.Toast;
13
14 public class U4_02_SpinnerAdapter extends Activity {
15
16 @Override
17 protected void onCreate(Bundle savedInstanceState) {
18 super.onCreate(savedInstanceState);
19 setContentView(R.layout.activity_u4_02__spinner_adapter);
20
21 Spinner spinFroitas = (Spinner) findViewById(R.id.spin_froitas);
22
23 // Fonte de datos
24 String[] froitas = new String[] { "Pera", "Mazá", "Plátano" };
25
26 // Enlace do adaptador cos datos
27 ArrayAdapter<String> adaptador = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, froitas);
28
29 // Opcional: layout usuado para representar os datos no Spinner
30 adaptador.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
31
32 // Enlace do adaptador co Spinner do Layout.
33 spinFroitas.setAdapter(adaptador);
34
35 // Escoitador
36 spinFroitas.setOnItemSelectedListener(new OnItemSelectedListener() {
37 @Override
38 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
39 //Toast.makeText(getBaseContext(), "Seleccionaches: " + parent.getItemAtPosition(pos), Toast.LENGTH_LONG).show();
40 Toast.makeText(getBaseContext(), "Seleccionaches: " + ((TextView) view).getText(), Toast.LENGTH_LONG).show();
41
42 }
43
44 @Override
45 public void onNothingSelected(AdapterView<?> arg0) {
46 // TODO Auto-generated method stub
47 }
48 }); // Fin da clase anónima
49
50 }
51
52 @Override
53 public boolean onCreateOptionsMenu(Menu menu) {
54 // Inflate the menu; this adds items to the action bar if it is present.
55 getMenuInflater().inflate(R.menu.u4_02__spinner_adapter, menu);
56 return true;
57 }
58
59 }
- Liña 23: Definimos a fonte de datos, neste caso un array estático.
- Liña 26: Definimos o adaptador de tipo ArrayAdapter. Pasámoslle como parámetros:
- Contexto,
- O int, identificador de recurso de layout que se vai usar para representar a Vista de Selección, neste caso usamos un predefinido. O usuario pode experimentar con outros tipos (android.R.layout.... CTRL+ESPAZO) e ver que outras formas hai de presentar os datos nun Spinner.
- Un array de obxectos, neste caso de Strings.
- Para ver outros construtores e métodos: http://developer.android.com/reference/android/widget/ArrayAdapter.html
- Liña 29: setDropDownViewResource(int), indica como se vai representar cada un dos ítems do Spinner. Usamos un layout xa predefinido. O usuario pode experimentar usando outros distintos, predefinidos ou propios.
- Liña 32: establece o adaptador que subministra os datos ao Spinner.
- Liña 35: O escoitador é o mesmo que cando non se usaba un adaptador.
- Liñas 38,39: As dúas liñas fan o mesmo, pero no segundo caso observar como recollemos a vista (view) que nos devolve o evento ao premer nun ítem do Spinner. Esa view é do tipo TextView e por iso facemos un cast e logo xa lle podemos aplicar métodos da clase TextView, como getText().
Usando un array de recursos XML
- Usamos o mesmo Layout do exemplo anterior e case o mesmo código, só comentamos a liña de asociación do adaptador coa fonte de datos e engadimos outra sentencia que asocie o adaptador co ficheiro XML.
Ficheiro XML para o array
- En res/values/array_froitas.xml
- Observar o nome do recurso array: froitas
1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3
4 <string-array name="froitas">
5 <item>Pera</item>
6 <item>Mazá</item>
7 <item>Plátano</item>
8 </string-array>
9
10 </resources>
O código Java do programa
1 package com.example.u4_02_spinneradapter;
2
3 import android.app.Activity;
4 import android.os.Bundle;
5 import android.view.Menu;
6 import android.view.View;
7 import android.widget.AdapterView;
8 import android.widget.AdapterView.OnItemSelectedListener;
9 import android.widget.ArrayAdapter;
10 import android.widget.Spinner;
11 import android.widget.Toast;
12
13 public class U4_02_SpinnerAdapter extends Activity {
14
15 @Override
16 protected void onCreate(Bundle savedInstanceState) {
17 super.onCreate(savedInstanceState);
18 setContentView(R.layout.activity_u4_02__spinner_adapter);
19
20 Spinner spinFroitas = (Spinner) findViewById(R.id.spin_froitas);
21
22 // Fonte de datos. Neste caso obtense dun recurso xml.
23 //String[] froitas = new String[] { "Pera", "Mazá", "Plátano" };
24
25 // Enlace do adaptador cos datos
26 // ArrayAdapter<String> adaptador = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, froitas);
27
28 ArrayAdapter<CharSequence> adaptador = ArrayAdapter.createFromResource(this, R.array.froitas, android.R.layout.simple_spinner_item);
29
30 // Opcional: layout usuado para representar os datos no Spinner
31 adaptador.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
32
33 // Enlace do adaptador co Spinner do Layout.
34 spinFroitas.setAdapter(adaptador);
35
36 // Escoitador
37 spinFroitas.setOnItemSelectedListener(new OnItemSelectedListener() {
38 @Override
39 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
40 //Toast.makeText(getBaseContext(), "Seleccionaches: " + parent.getItemAtPosition(pos), Toast.LENGTH_LONG).show();
41 Toast.makeText(getBaseContext(), "Seleccionaches: " + ((TextView) view).getText(), Toast.LENGTH_LONG).show();
42
43 }
44
45 @Override
46 public void onNothingSelected(AdapterView<?> arg0) {
47 // TODO Auto-generated method stub
48 }
49 }); // Fin da clase anónima
50
51 }
52
53 @Override
54 public boolean onCreateOptionsMenu(Menu menu) {
55 // Inflate the menu; this adds items to the action bar if it is present.
56 getMenuInflater().inflate(R.menu.u4_02__spinner_adapter, menu);
57 return true;
58 }
59
60 }
- Liña 26: Comentamos o anterior construtor e ...
- Liña 28: usamos outro método que nos permita ler un recurso XML: createFromResource(this, R.array.froitas, android.R.layout.simple_spinner_item)
- Contexto,
- Nome do recurso array que contén os ítems,
- O int, identificador de recurso de layout que se vai usar para representar a Vista de Selección, neste caso usamos un predefinido. O usuario pode experimentar con outros tipos (android.R.layout.... CTRL+ESPAZO) e ver que outras formas hai de presentar os datos nun Spinner.
- Para ver outros construtores e métodos: http://developer.android.com/reference/android/widget/ArrayAdapter.html
- No canto de facer cambiar de método puidemos usar o construtor que usamos no primeiro caso:
- Pero antes recollemos o array XML nun array de Strings de datos: String[] froitas = getResources().getStringArray(R.array.froitas);
- O resto non varía.
Uso dun array dinámico
- Nos dous casos anteriores o contido do Spinner é estático e defínese en tempo de compilación, non de execución.
- Se usamos arrays dinámicos podemos crear a fonte de datos en tempo de execución antes de pasarlla ao adaptador.
- Así imos poder usar datos de ficheiros, bases de datos, etc e crear unha fonte de datos para un Spinner en tempo de execución.
1 package com.example.u4_02_spinneradapter;
2
3 import java.util.ArrayList;
4 import android.R.string;
5 import android.app.Activity;
6 import android.os.Bundle;
7 import android.view.Menu;
8 import android.view.View;
9 import android.widget.AdapterView;
10 import android.widget.AdapterView.OnItemSelectedListener;
11 import android.widget.ArrayAdapter;
12 import android.widget.Spinner;
13 import android.widget.Toast;
14
15
16 public class U4_02_SpinnerAdapter extends Activity {
17
18 @Override
19 protected void onCreate(Bundle savedInstanceState) {
20 super.onCreate(savedInstanceState);
21 setContentView(R.layout.activity_u4_02__spinner_adapter);
22
23 Spinner spinFroitas = (Spinner) findViewById(R.id.spin_froitas);
24
25 // Fonte de datos
26 // String[] froitas = new String[] { "Pera", "Mazá", "Plátano" };
27
28 ArrayList<String> froitas = new ArrayList<String>();
29
30 froitas.add("Pera");
31 froitas.add("Mazá");
32 froitas.add("Plátano");
33
34 // Enlace do adaptador cos datos
35 ArrayAdapter<String> adaptador = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, froitas);
36
37 // Opcional: layout usuado para representar os datos no Spinner
38 adaptador.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
39
40 // Enlace do adaptador co Spinner do Layout.
41 spinFroitas.setAdapter(adaptador);
42
43 // Escoitador
44 spinFroitas.setOnItemSelectedListener(new OnItemSelectedListener() {
45 @Override
46 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
47 //Toast.makeText(getBaseContext(), "Seleccionaches: " + parent.getItemAtPosition(pos), Toast.LENGTH_LONG).show();
48 Toast.makeText(getBaseContext(), "Seleccionaches: " + ((TextView) view).getText(), Toast.LENGTH_LONG).show();
49 }
50
51 @Override
52 public void onNothingSelected(AdapterView<?> arg0) {
53 // TODO Auto-generated method stub
54 }
55 }); // Fin da clase anónima
56
57 }
58
59 private String[] getStringArray(int froitas) {
60 // TODO Auto-generated method stub
61 return null;
62 }
63
64 @Override
65 public boolean onCreateOptionsMenu(Menu menu) {
66 // Inflate the menu; this adds items to the action bar if it is present.
67 getMenuInflater().inflate(R.menu.u4_02__spinner_adapter, menu);
68 return true;
69 }
70
71 }
- Liñas 23-28: Neste caso os elementos do array engádense en tempo de execución ao array froitas, que neste caso e do tipo ArrayList.
- O resto é exactamente igual.
-- Ángel D. Fernández González e Carlos Carrión Álvarez -- (2015).