= $u_time + 86400) { $modifiedDate = get_the_modified_time('F jS, Y'); echo 'Última modificación: '.$modifiedDate.''; } }?>

Cómo implementar ListView en Android optimizando al máximo el código

La clave aquí es conseguir aislar el código encargado de crear nuestra celda en el Adaptador, logrando así separar las responsabilidades de la vista y del controlador; ya que éste no tiene necesidad de saber qué es exactamente lo que se muestra en la vista, sino solo un objeto. Pero vamos por partes:

Crear la lista en la vista:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:orientation="vertical">

	<ListView
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:id="@+id/listView"/>
</RelativeLayout>

Crear y rellenar una lista con los datos de nuestro modelo, en este caso usaremos una Entidad llamada Movie, cuyos únicos atributos son title y description.

public class MainActivity extends Activity
{
	ListView list;
	MoviesListAdapter adapter;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// Recordar que listView equivale al nombre único dado a la lista en el xml: android:id="@+id/listView"
		list = (ListView) findViewById(R.id.listView);

		List<Movie> moviesList = new ArrayList<Movie>();
		for(int i = 1; i < 20; i++)
		{
			moviesList.add(new Movie("titulo " + i, null, "descripcion " + i));
		}

		adapter = new MoviesListAdapter(this, moviesList);
		list.setAdapter(adapter);
	}
}  

Crear el Adaptador de la lista

public class MoviesListAdapter extends BaseAdapter
{
	private final LayoutInflater inflater;
	private Context context;
	private List<Movie> moviesList;

	public MoviesListAdapter(Context c, List<Movie> list)
	{
		this.context = c;
		this.moviesList = list;
		this.inflater = LayoutInflater.from(context);
	}

	@Override
	public int getCount()
	{
		return this.moviesList.size();
	}

	@Override
	public Movie getItem(int position)
	{
		return this.moviesList.get(position);
	}

	@Override
	public long getItemId(int position)
	{
		return 0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent)
	{
		MovieView view;
		if (convertView == null) {
			view = (MovieView) inflater.inflate(R.layout.movies_rows, null);
		} else {
			view = (MovieView) convertView;
		}
		Movie item = getItem(position);
		view.showMovie(item);
		return view;
	}
}

La parte más importante hasta aquí es el método getView de nuestro Adaptador:

@Override
	public View getView(int position, View convertView, ViewGroup parent)
	{
		MovieView view;
		if (convertView == null) {
			view = (MovieView) inflater.inflate(R.layout.movies_rows, null);
		} else {
			view = (MovieView) convertView;
		}
		Movie item = getItem(position);
		view.showMovie(item);
		return view;
	}

“MovieView” es la clase encargada de alojar los componentes que mostrará nuestra vista. Como veis, el comportamiento de éste método es muy similar a como se suele ver implementado en la mayoría de los ejemplos; sin embargo, de esta manera evitamos rellenar aquí todo los datos que mostrará nuestra celda delegando este comportamiento en otra clase.

Primero crearemos la clase MovieView:

public class MovieView extends RelativeLayout
{
	private TextView titleView;
	private TextView descriptionView;

	@Override
	protected void onFinishInflate()
	{
		super.onFinishInflate();
		titleView = (TextView) findViewById(R.id.title);
		descriptionView = (TextView) findViewById(R.id.description);	}

	public void showMovie(Movie movie)
	{
		titleView.setText(movie.getTitle());
		descriptionView.setText(movie.getDescription());
	}

	/**
	 * Inherited constructor.
	 */
	public MovieView(Context context)
	{
		super(context);
	}

	/**
	 * Inherited constructor.
	 */
	public MovieView(Context context, AttributeSet attrs)
	{
		super(context, attrs);
	}

	/**
	 * Inherited constructor.
	 */
	public MovieView(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);
	}
}

Y ahora creamos nuestro xml con lo que queremos que muestre la celda:

<com.boletus151.quierover.adapters.MovieView
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="?android:attr/listPreferredItemHeight"
	android:padding="6dip">

	<TextView
		android:id="@+id/title"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_toRightOf="@id/poster"
		android:text="title text"
		/>
	<TextView
		android:id="@+id/description"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_toRightOf="@id/poster"
		android:layout_below="@id/title"
		android:layout_marginTop="5dp"
		android:text="description text"
		/>
</com.boletus151.quierover.adapters.MovieView>

 

Poned mucha atención en esta línea:

com.boletus151.quierover.adapters.MovieView

es la que le indica a la celda de qué “tipo” es.

¡Y esto es todo!

Os dejo unos links en los que podréis leer más cosas acerca de este tema. Este tutorial ha sido sacado a partir de la información de estas páginas:

http://architects.dzone.com/articles/viewholder-considered-harmful

https://www.bignerdranch.com/blog/customizing-android-listview-rows-subclassing/

Leave a Reply

Your email address will not be published. Required fields are marked *