Layout_width de un ListView

Ok, me encontré con un problema con el attribut layout_width de un listView.

En mi proyecto, tenía una imagen de fondo para mi vista de lista que no se ajustaba al ancho de la pantalla. Así que establecí el layout_width en wrap_content, y centré horizontalmente el listView.

Parece que esta fue una mala idea, porque en el adaptador el método GetView se llamó más de 3 veces la cantidad de celdas mostradas. Si configuro el layout_width en fill_parent, el problema se resuelve. Creé un proyecto simple que muestra el problema.

Aquí está el xml de la actividad:

    

El item_list xml:

    

Y finalmente la Actividad:

 package fr.example.android.listviewbug; import android.app.ListActivity; import android.content.Context; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; public class ExampleListViewBugActivity extends ListActivity{ public static int cpt; public static final String[] COUNTRIES = new String[] { "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory", "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde", "Cayman Islands", "Central African Republic", "Chad", "Chile"}; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); cpt = 0; setListAdapter(new CustomArrayAdapter(this, R.layout.list_item, COUNTRIES)); } @Override public void onDestroy() { super.onDestroy(); Log.d("AdapterTest", "onDestroy()"); } private class CustomArrayAdapter extends ArrayAdapter{ public CustomArrayAdapter(Context context, int textViewResourceId, String[] countries) { super(context, textViewResourceId, countries); } @Override public View getView(int position, View convertView, ViewGroup parent) { Log.d("AdapterTest", " cpt:"+ ++cpt); return super.getView(position, convertView, parent); } } } 

Así que mi solución es simplemente configurar el layout_width en fill_parent y modificar la imagen del fondo de la vista de lista para agregar algunos bordes transparentes que se ajusten al tamaño de la pantalla.

Pero me gustaría saber por qué aparece este problema con wrap_content en una vista de lista, y por qué no está en el documento si se trata de un problema conocido …

Al establecer el ancho en “wrap_content” le está diciendo a ListView que sea tan ancho como el más amplio de sus hijos. ListView debe por lo tanto medir sus elementos y obtener los elementos que tiene que llamar getView () en el Adaptador. Esto puede suceder varias veces dependiendo de la cantidad de pases de disposición, el comportamiento del diseño principal, etc.

Recuerde que no hay garantías sobre la cantidad de veces que se invoca getView () en el Adaptador, ni en qué órdenes se realizarán las llamadas. Por lo tanto, debe implementar getView () para que sea lo más eficiente posible. La conclusión es que esto no es un problema, es el comportamiento esperado en esta situación.

La respuesta es simple: si configura el ancho de diseño o la altura de diseño de su ListView a wrap_content ListView intentará medir cada vista que se le atribuye, que definitivamente no es lo que desea.

En términos generales, evite establecer wrap_content para ListViews o GridViews en todo momento.