Android: diseño de xml para una lista con diferentes elementos

Estoy leyendo este tutorial http://android.amberfog.com/?p=296 . Me gustaría crear una lista con diferentes tipos de filas. Entiendo cómo crear el adaptador, pero ¿qué pasa con el diseño xml? Así que definire un diseño xml como este:

<ListView/> <TextView android:id="@+id/id1" /> <TextView android:id="@+id/id2" /> <ImageView android:id="@+id/id3" /> <TextView android:id="@+id/id4" /> 

¿Será un problema (para el rendimiento) si tal vez una fila utiliza sólo algunos elementos (sólo algunas textviews) del diseño y otra fila puede utilizar otros elementos? No entiendo si el mío es la forma correcta de definir el xml o si tengo que crear un diseño diferente para cada tipo de fila.

Gracias de antemano

EDIT: ahora estoy teniendo una excepción de punto nulo.

Código java del adaptador:

 @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; int type = getItemViewType(position); if (convertView == null) { holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.listview_main, null); holder.textView_title = (TextView)convertView.findViewById(R.id.listview1); convertView.setTag(holder); } else { holder = (ViewHolder)convertView.getTag(); } **holder.textView_title.setText("aaaa");** //NULL POINT EXCEPTION HERE return convertView; 

}

 class ViewHolder { public TextView textView_title; } 

Xml 1:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="left" android:layout_margin="0dp"> <!-- android:background="#0094ff" --> <ListView android:id="@id/android:list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:fastScrollEnabled="true" android:scrollbarStyle="insideInset" android:textFilterEnabled="false" android:divider="@null" android:layout_margin="0dp" android:paddingTop="0dp" android:paddingBottom="0dp" android:paddingLeft="15dp" android:paddingRight="22dp"/> </LinearLayout> 

Xml2

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="left" android:layout_margin="0dp"> <TextView android:id="@+id/listview1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingTop="7dp" android:paddingBottom="0dp" android:paddingLeft="0dp" android:paddingRight="0dp" android:textSize="18sp" android:textColor="#000000" android:lines="1"> </TextView> </LinearLayout> 

4 Solutions collect form web for “Android: diseño de xml para una lista con diferentes elementos”

Necesita reemplazar getViewItemType y getViewTypeCount . También necesitará diseños personalizados.

getItemViewType(int position) – devuelve la información que tipo de diseño debe usar basado en la posición.

Usted debe echar un vistazo al video en el enlace.

http://www.youtube.com/watch?v=wDBM6wVEO70

 private static final int TYPE_ITEM1 = 0; private static final int TYPE_ITEM2 = 1; private static final int TYPE_ITEM3 = 2; 

Entonces

 int type; @Override public int getItemViewType(int position) { if (position== 0){ type = TYPE_ITEM1; } else if (position == 1){ type = TYPE_ITEM2; } else { type= TYPE_ITEM3 ; } return type; } @Override public int getViewTypeCount() { return 3; } @Override public View getView(int position, View convertView, ViewGroup parent) { View row = convertView; LayoutInflater inflater = null; int type = getItemViewType(position); // instead of if else you can use a case if (row == null) { if (type == FIRST_TYPE) { //infalte layout of type1 } if (type == SECOND_TYPE) { //infalte layout of type2 } else { //infalte layout of normaltype } } 
  • Acabo de resolver este problema de crear diversas disposiciones para las filas diferentes.
    1. Defina todos los diseños diferentes en sus correspondientes archivos xml diferentes.
    2. Anule el método getViewTypeCount () y devuelva el número de diseños definidos a partir de este.
    3. El método override getItemViewType () y de acuerdo con la relación entre la 'posición' del elemento en el listview y el diseño xml propuesto definen la condición y devuelven los valores enteros apropiados.
    4. Al llamar al método getItemViewType () en el método getView (), podemos obtener el número correspondiente al diseño, a continuación, inflar el convertView con el diseño xml correspondiente. Y luego usando findViewById (), puede obtener los valores en objetos de la clase TextView definidos en la clase ViewHolder y setText o cualquier operación que desee utilizar, puede hacer más. Tan simple como es. Supongamos que tenemos 4 tipos de diseños y 4 archivos XML denominados como elemento1, elemento2, elemento3, elemento4 y dos texto común id como texto1, texto2.

@Override public int getItemViewType(int position) { if (position % 4 == 0) { return 0; } else if (position % 4 == 1) { return 1; } else if (position % 4 == 2) { return 2; } return 3; }

  public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; int type = getItemViewType(position); if (convertView == null) { switch (type) { case 0: { convertView = mInflater.inflate(R.layout.element1, null); break; } case 1: { convertView = mInflater.inflate(R.layout.element2, null); break; } case 2: { convertView = mInflater.inflate(R.layout.element3, null); break; } case 3: { convertView = mInflater.inflate(R.layout.element4, null); break; } } holder = new ViewHolder(); holder.txt1 = (TextView) convertView.findViewById(R.id.text1); holder.txt2 = (TextView) convertView.findViewById(R.id.text2); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } String rowItem = null; rowItem = rowItems[position]; holder.txt1.setText(rowItem); rowItem = rowItems[position+1]; holder.txt1.setText(rowItem); return convertView; } private class ViewHolder { TextView txt1, txt2; } 

Esto podría ser un método incorrecto para hacerlo. Si sólo tiene un componente en ListView, utilice un adaptador simple o utilice un adaptador personalizado con un XML separado para la fila de lista.

Código de muestra:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listhistory); initcomponents(); ArrayList<HashMap<String, String>> alist = new ArrayList<HashMap<String, String>>(); for (int i = 1; i < 20; i++) { HashMap<String, String> hmap = new HashMap<String, String>(); hmap.put("date", "" + i + "/13"); hmap.put("restaurant", "Restaurant" + i); hmap.put("distance", "" + (i * 100) + "kms"); alist.add(hmap); } final CustomListAdapter adapter = new CustomListAdapter(this, R.layout.listitemhistory, alist); list.setAdapter(adapter); } private void initcomponents() { list = (ListView) findViewById(R.id.history_lst_list); } public void backButtonClick(View v) { finish(); } class CustomListAdapter extends ArrayAdapter<HashMap<String, String>> { Context context; int textViewResourceId; ArrayList<HashMap<String, String>> alist; public CustomListAdapter(Context context, int textViewResourceId, ArrayList<HashMap<String, String>> alist) { super(context, textViewResourceId); this.context = context; this.alist = alist; this.textViewResourceId = textViewResourceId; } public int getCount() { return alist.size(); } public View getView(int pos, View convertView, ViewGroup parent) { Holder holder = null; LayoutInflater inflater = ((Activity) context) .getLayoutInflater(); convertView = inflater.inflate(R.layout.listitemhistory, parent, false); holder = new Holder(); holder.date = (TextView) convertView .findViewById(R.id.listitemhistory_txt_date); holder.restaurant = (TextView) convertView .findViewById(R.id.listitemhistory_txt_restaurant); holder.distance = (TextView) convertView .findViewById(R.id.listitemhistory_txt_distance); holder.lin_background = (LinearLayout) convertView .findViewById(R.id.history_lin_background); convertView.setTag(holder); holder = (Holder) convertView.getTag(); holder.date.setText(alist.get(pos).get("date")); holder.restaurant.setText(alist.get(pos).get("restaurant")); holder.distance.setText(alist.get(pos).get("distance")); return convertView; } class Holder { TextView date, restaurant, distance; LinearLayout lin_background; } } 

No será un problema. Pero creo que tienes el tutorial equivocado.

Su necesidad de definir un diseño para una fila.

Si desea que su fila pueda contener un texto o una imagen, debe agregar ambas vistas al diseño.

Ahora en usted adaptador, donde usted llena su lista usted decide qué artículo fijar.

Así que digamos que tienes 2 cuerdas y una imagen.

Por lo tanto, establece el texto para las dos primeras filas y agrega una imagen a la tercera. No tienes que predefine cada fila por sí mismo, como supongo que eso es lo que estás tratando de hacer.

  • ¿Patrón de diseño para extender las actividades de Android?
  • Quiero google play store como scrollview
  • Implementación de la retroinstalación adecuada y manejo de botones de inicio mediante la barra de herramientas en Android
  • Agregar vista al grupo de vistas xml existente en el código
  • ¿Cómo puedo crear un diseño con pestañas completamente en XML?
  • ImageView problema
  • ¿Cómo puedo replicar este patrón de interfaz de usuario: haga clic en el elemento ListView y expanda debajo de él?
  • Android admob no mostrar en pantalla tamaño demasiado pequeño
  • Material Tema Android Action Bar Estilo Generador
  • Vista personalizada que divide el diseño en diagonal con diferentes vistas secundarias
  • Combinar lienzo y diseño (Android)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.