domingo, 9 de febrero de 2014

Adaptadores

Para los elementos compuestos del interfaz como listas o componentes de selección es necesario emplear adaptadores que proporcionen la información necesaria.

La forma más sencilla de adaptador es emplear un adaptador del sistema empleando recursos estáticos, aunque Android también permite emplear adaptadores personalizados con datos provenientes de orígenes distintos que además son configurables en aspecto y comportamiento.

Lo mínimo necesario

Definir un adaptador para mostrar la información:
ListView listView1 = (ListView) findViewById(R.id.lvLista);
//Datos
String[] items = { "Leche", "Huevos", "Harina" };
       
//Definir y asignar el adaptador
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, items);
listView1.setAdapter(adapter);


También es posible definir los datos en fichero de recursos:
<string-array name="precios">       
       <item>15€/mes</item>
       <item>20€/mes</item>
       <item>Gratuito</item>
</string-array>


El ArrayAdapter para el componente se genera de forma similar:
Spinner sp = (Spinner) findViewById(R.id.spPrecios);
ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(this,
      R.array.precios, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);

sp.setAdapter(adapter);


Un adaptador NO se restringe simplemente a cadenas de caracteres, se puede definir un adaptador para cualquier clase de la aplicación:
//Se utiliza el método toString de Provincia a la hora de mostrar
ArrayAdapter<Provincia> adapter = new ArrayAdapter<Provincia>(this,
android.R.layout.simple_list_item_1, items);

listView1.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener(){
  @Override
  public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
    //Obtener la provincia seleccionada
    Provincia p = (Provincia) parent.getAdapter().getItem(position);
    …
  }
});


Adaptadores Personalizados

Se puede generar un adaptador personalizado para representar instancias de objetos que no se limiten simplemente a mostrar el texto representativo, sino que también puedan mostrar otra información de los objetos, modificar la disposición de elementos en pantalla, estilos, …

Definir un ListView dentro del layout de la Activity:
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
       
        <ListView
            android:id="@+id/lvLista"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        </ListView>
</LinearLayout>


Establecer un layout (list_item) que representa cada uno de los elementos a mostrar:
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:background="@android:color/transparent"
    android:cacheColorHint="@android:color/transparent"
    android:padding="5dp">
   
    <LinearLayout
        android:id="@+id/imgLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_marginRight="5dp"
        android:padding=“3dp">

        <ImageView
            android:id="@+id/ivImagen"
            android:layout_width="50dp"
            android:layout_height="50dp"/>
    </LinearLayout>
   
    <TextView
        android:id="@+id/tvNombre"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:textSize="15dp"
        android:layout_alignTop="@id/imgLayout"
        android:layout_toRightOf=“@id/imgLayout”/>

    <TextView
        android:id="@+id/tvDescripcion"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/tvNombre"
        android:layout_toRightOf="@id/imgLayout"
        android:layout_marginTop="1dip" />
   
</RelativeLayout>


Definir el adaptador de listas para la clase Empleado:
public class EmpleadoAdapter extends ArrayAdapter<Empleado> {
  private ArrayList<Empleado> elementos;
  private Context context;
  private int resourceId;

  public EmpleadoAdapter(Context context, int resourceId,
                  ArrayList<Empleado> elementos) {
super(context, resourceId, elementos);
      this.elementos = elementos;
this.context = context;
this.resourceId = resourceId;
  }

  @Override
  public View getView(int pos, View convertView, ViewGroup parent)
//Evita llamadas innecesarias a findViewById
ViewElemento holder;
// Evitar reinflar los componentes
if (convertView == null) {
  LayoutInflater vi = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = vi.inflate(R.layout.list_item, null);
        holder = new ViewElemento();
        holder.texto =
            (TextView) convertView.findViewById(R.id.tvNombre);
        holder.descripcion =
            (TextView) convertView.findViewById(R.id.tvDescripcion);
        holder.foto =
            (ImageView) convertView.findViewById(R.id.ivImagen);
        convertView.setTag(holder);
      } else {
        holder = (ViewElemento) convertView.getTag();
      }
      Empleado emp = elementos.get(pos);
      if (emp != null) {
        // Construir el elemento
        holder.texto.setText(emp.getNombre()); 
  holder.descripcion.setText(emp.getPuesto());
        holder.foto.setImageDrawable(emp.getFoto());
}
                 
      return convertView;
  }

  public int getCount() {
      return elementos.size();
  }

  public Empleado getItem(int position) {
      return elementos.get(position);
  }

  public long getItemId(int position) {
      return position;
  }

  static class ViewElemento {
      ImageView foto;
      TextView texto;
TextView descripcion;
  }
}

Establecer el adaptador de listas:
listView = (ListView) findViewById(R.id.lvEmpleados);
// Permitir lista con fondo transparente
listView.setCacheColorHint(0);

// Cargar el adaptador de listas
listView.setAdapter(new EmpleadosAdapter(this, R.layout.list_item, lista));

listView.setOnItemClickListener(this);


Referencias





No hay comentarios:

Publicar un comentario