Imprimir

Mostrar registros de muestra en la lista

Para mostrar los registros de ejemplo que se han añadido en el List de la clase Persons en la lista que se muestra en pantalla al iniciar la aplicación, se debe modificar el metodo onCreate de la clase PersonListFragment. Ese método es ejecutado automáticamente cuando el Fragment es creado, por lo que puede ser un buen momento pasa cargar la lista con los registros de muestra llamando al método loadSimpleSamples de la clase Persons y modificar el adaptador de la lista que aparece en pantalla para que en lugar de mostrar los valores de la plantilla (Item1, Item2, etc), muestre los valores añadidos en la lista personList.

Por tanto, se comprobará si la lista está vacía, y en ese caso se añadirán los datos de muestra en la lista. Esta comprobación se realiza para evitar que la lista se rellene más de una vez, que provocaría la repetición de registros, ya que el método onCreate de la clase PersonListFragment se puede ejecutar varias veces sin que la aplicación haya finalizado totalmente (repasa el ciclo de vida de los Fragment). En caso de que la lista esté vacía, se rellenará con los datos de muestra ejecutando el método loadSimpleSamples que se ha creado en la clase Persons.

A continuación se invocará al método setListAdapter (de manera muy parecida a la que ha generado el asistente de creación del proyecto), indicando por parámetro que se va a usar una lista de objetos de tipo Person, y en el último parámetro se indicará la lista que contiene los datos (Persons.personList).

Observa que se han comentado algunas de las líneas que había generado el asistente. Todas esas líneas deben ser eliminadas a partir de este momento.

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        // TODO: replace with a real list adapter.
//        setListAdapter(new ArrayAdapter<DummyContent.DummyItem>(
//                getActivity(),
//                android.R.layout.simple_list_item_activated_1,
//                android.R.id.text1,
//                DummyContent.ITEMS));
        if(Persons.personList.isEmpty()) {
            Persons.loadSimpleSamples();
        }
        setListAdapter(new ArrayAdapter<Person>(
                getActivity(),
                android.R.layout.simple_list_item_activated_1,
                android.R.id.text1,
                Persons.personList));
    }

Si ejecutas en este momento la aplicación podrás ver que ya se muestra el contenido de la lista lista aunque de una manera poco agradable para el usuario, ya que para mostrar los objetos contenidos en la lista se usa de manera predefinida el valor retornado por el método toString de la clase Person

 

Personalización de la vista de los elementos de la lista

Ahora se pretende que la lista sea más personalizada. Por defecto, la lista se crea de manera que únicamente se muestra una línea de texto por cada entrada. Ahora vamos a intentar mostrar una imagen, un texto principal y otro secundario para cada elemento de la lista. El resultado será similar al que se muestra en la siguiente imagen:

Layout person_row_adapter.xml

En primer lugar se ha creado un nuevo layout con la estructura que se ha querido tener para cada elemento de la lista. En este ejemplo se ha querido hacer con dos líneas de texto principal y secundario junto a una imagen para el icono de favorito. Por tanto, el layout ha quedado como se muestra a continuación:

<?xml version="1.0" encoding="utf-8"?>
 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
 
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="Large Text"
            android:id="@+id/textViewAlias"
            android:enabled="false" />
 
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:text="Small Text"
            android:id="@+id/textViewFullName" />
 
    </LinearLayout>
 
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:layout_gravity="right"
        android:gravity="right">
 
        <ImageView
            android:layout_width="32dp"
            android:layout_height="wrap_content"
            android:id="@+id/imageViewFavorite"
            android:layout_margin="5dp" />
    </LinearLayout>
 
</LinearLayout>

Llamada al método setListAdapter

Para realizar esta personalización de los elementos de la lista hay que crear una clase Java heredada de la clase ArrayAdapter. Si observas el primer apartado, se utilizaba una llamada al método setListAdapter al que se le pasa por parámetro un objeto ArrayAdapter para convertir el contenido del ArrayList que contiene los datos a una lista que se pueda mostrar en pantalla.

En el caso que estamos tratando, hay que pasar al método setListAdapter un objeto de dicha clase hija de ArrayAdapter. Como veremos posteriormente, la nueva clase heredada de ArrayAdapter personalizada la vamos a llamar PersonsArrayAdapter, a la que haremos un método constructor que tenga únicamente como parámetros el contexto (getActivity()) y la lista de datos. Por tanto, el código quedará así:

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        if(Persons.personList.isEmpty()) {
            Persons.loadSimpleSamples();
        }
//        setListAdapter(new ArrayAdapter<Person>(
//                getActivity(),
//                android.R.layout.simple_list_item_activated_1,
//                android.R.id.text1,
//                Persons.personList));
        setListAdapter(new PersonsArrayAdapter(getActivity(), Persons.personList));
    }

Recuerda que previamente se había cargado la lista de datos con algunos casos de ejemplo usando Persons.loadSimpleSamples(), y eso debe permanecer igual.

Clase Java PersonsArrayAdapter

Este es el código que se ha utilizado para crear la clase Java PersonsArrayAdapter: (se ha guardado en un paquete nuevo llamado adapters por organización)

package es.javiergarciaescobedo.addressbookdroid.adapters;
 
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
 
import java.util.List;
 
import es.javiergarciaescobedo.addressbookdroid.R;
import es.javiergarciaescobedo.addressbookdroid.models.Person;
 
public class PersonsArrayAdapter extends ArrayAdapter {
 
    private final Context context;
 
    private final List<Person> personList; //Lista de objetos que va a contener la lista
 
    /**
     * Constructor que permite cargar las propiedades de esta clase, y que llama inicialmente 
     * al constructor original de ArrayAdapter indicando el nombre del layout (person_row_layout)
     *
     * @param context    Contexto (p.e. getActivity())
     * @param personList Lista de objetos que va a contener la lista
     */
    public PersonsArrayAdapter(Context context, List personList) {
        super(context, R.layout.person_row_adapter, personList);
        this.context = context;
        this.personList = personList;
    }
 
    /* Sobrecargar el método getView para rellenar el elemento de la lista con los valores
    almacenados en la propiedad values de esta clase
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
 
        // Asociar este ArrayAdpater con el layout 'person_row_adapter' que se ha creado
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.person_row_adapter, parent, false);
 
        //Obtener el objeto Person correspondiente a la posición de la lista que ha seleccionado el usuario
        Person person = personList.get(position);
 
        //Cargar en el TextView de letra grande el alias del contacto
        TextView textViewAlias = (TextView) rowView.findViewById(R.id.textViewAlias);
        textViewAlias.setText(person.getAlias());
 
        //Cargar en el TextView de letra pequeña el nombre completo del contacto
        TextView textViewFullName = (TextView) rowView.findViewById(R.id.textViewFullName);
        textViewFullName.setText(person.getSurnames() + ", " + person.getName());
 
        //Cargar el icono correspondiente si el contacto está marcado como favorito
        ImageView imageViewPhoto = (ImageView) rowView.findViewById(R.id.imageViewFavorite);
        if(person.isFavorite()) {
            int id = context.getResources().getIdentifier("drawable/favorite", "drawable", context.getPackageName());
            imageViewPhoto.setImageDrawable(context.getResources().getDrawable(id));
        } else {
            imageViewPhoto.setImageDrawable(null);
        }
 
        return rowView;
    }
} 

Código fuente

Puedes ver el código fuente del proyecto hasta este punto en el siguiente commit del proyecto alojado en GitHub:

https://github.com/javiergarciaescobedo/AddressBookDroid/tree/8fde5d98a728314664836ca1f4b2449cc108dbd3

 

Ver todos los artículos de este tutorial