Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Creación de ViewHolders para ListViews con diferentes diseños de elementos

Tengo un ListView con diversas disposiciones para diversos artículos. Algunos artículos son separadores. Algunos artículos son diferentes porque contienen diferentes tipos de datos, etc.

Quiero implementar ViewHolders para acelerar el proceso getView, pero no estoy muy seguro de cómo hacerlo. Los diferentes diseños tienen diferentes partes de datos (lo que dificulta la asignación de nombres) y diferentes números de vistas que quiero usar.

¿Cómo debo hacer esto?

La mejor idea que se me ocurre es crear un ViewHolder genérico con elementos X donde X es el número de vistas en un diseño de elementos con el mayor número de ellas. Para las otras vistas con un número pequeño de vistas, utilizaré solamente una subsección de esas variables en el ViewHolder. Así que decir que tengo 2 diseños que uso para 2 artículos diferentes. Uno tiene 3 TextViews y el otro tiene 1. Crearía un ViewHolder con 3 variables de TextView y utilizaría solamente 1 de ellas para mi otro artículo. Mi problema es que esto puede llegar a ser muy feo y se siente realmente hacky; Especialmente cuando una disposición del artículo puede tener muchas vistas de muchos diversos tipos.

Aquí hay un getView muy básico:

@Override public View getView(int position, View convertView, ViewGroup parent) { MyHolder holder; View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.layout_mylistlist_item, parent, false); holder = new MyHolder(); holder.text = (TextView) v.findViewById(R.id.mylist_itemname); v.setTag(holder); } else { holder = (MyHolder)v.getTag(); } MyListItem myItem = m_items.get(position); // set up the list item if (myItem != null) { // set item text if (holder.text != null) { holder.text.setText(myItem.getItemName()); } } // return the created view return v; } 

Supongamos que tenía diferentes tipos de diseños de filas, podría tener un ViewHolder para cada tipo de fila. Pero, ¿qué tipo de declaro "titular" para estar en la cima? ¿O podría declarar un titular para cada tipo y luego usar el del tipo de fila en el que estoy.

  • ListActivity TwoLineListItem Alternativa
  • Android: ¿Cómo tener un menú compartido en cada actividad (lista) sin volver a escribir los métodos anulados?
  • Android ListView en el fragmento
  • Agregar botones a una listactividad
  • Android SimpleCursorAdapter no se actualiza cuando cambia la base de datos
  • ¿Cuáles son las diferencias entre extender la actividad y extender ListActivity?
  • Problema al agregar pie de página a ListView
  • GetLoaderManager en ListActivity
  • 2 Solutions collect form web for “Creación de ViewHolders para ListViews con diferentes diseños de elementos”

    ListView tiene un sistema de gestión de tipos incorporado. En su adaptador, tiene varios tipos de elementos, cada uno con su propia vista y diseño. Al sobreescribir getItemViewType para devolver el tipo de datos de una posición determinada, ListView se garantiza pasar la conversión correcta para ese tipo de datos. Luego, en su método getView, simplemente compruebe el tipo de datos y utilice una instrucción switch para manejar cada tipo de forma diferente.

    Cada tipo de diseño debe tener su propio visor para nombrar claridad y facilidad de mantenimiento. Nombre el ViewHolders algo relacionado con cada tipo de datos para mantener todo recto.

    Tratar de superponer todo en un solo ViewHolder no merece la pena.

    Editar ejemplo

     @Override public View getView(int position, View convertView, ViewGroup parent) { int viewType = this.getItemViewType(position); switch(viewType) { case TYPE1: Type1Holder holder1; View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater)getContext().getSystemService (Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.layout_mylistlist_item_type_1, parent, false); holder1 = new Type1Holder (); holder1.text = (TextView) v.findViewById(R.id.mylist_itemname); v.setTag(holder1); } else { holder1 = (Type1Holder)v.getTag(); } MyListItem myItem = m_items.get(position); // set up the list item if (myItem != null) { // set item text if (holder1.text != null) { holder1.text.setText(myItem.getItemName()); } } // return the created view return v; case TYPE2: Type2Holder holder2; View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.layout_mylistlist_item_type_2, parent, false); holder2 = new Type2Holder (); holder2.text = (TextView) v.findViewById(R.id.mylist_itemname); holder2.icon = (ImageView) v.findViewById(R.id.mylist_itemicon); v.setTag(holder1); } else { holder2 = (Type2Holder)v.getTag(); } MyListItem myItem = m_items.get(position); // set up the list item if (myItem != null) { // set item text if (holder2.text != null) { holder2.text.setText(myItem.getItemName()); } if(holder2.icon != null) holder2.icon.setDrawable(R.drawable.icon1); } // return the created view return v; default: //Throw exception, unknown data type } } 

    Otro ejemplo.

    Public class CardArrayAdapter extends ArrayAdapter {

     public CardArrayAdapter(Context context) { super(context, R.layout.adapter_card); } @Override public View getView(int position, View view, ViewGroup parent) { final Card card = getItem(position); ViewHolder holder; //if (view != null) { //holder = (ViewHolder) view.getTag(); //} else { Log.d("card.important?", card.name + " = " + Boolean.toString(card.important)); if(card.important) { view = LayoutInflater.from(getContext()).inflate(R.layout.adapter_card_important, parent, false); }else { view = LayoutInflater.from(getContext()).inflate(R.layout.adapter_card, parent, false); } holder = new ViewHolder(view); view.setTag(holder); //} // IMG Picasso.with(getContext()) .load(card.logo) .placeholder(R.drawable.ic_phonebook) .error(R.drawable.ic_phonebook) .fit() .centerCrop() .transform(new CircleTransform()) .into(holder.logo); holder.name.setText(card.name); if(card.important) { holder.category.setVisibility(View.VISIBLE); if (card.category.equals("airline")) { card.category = "airlines"; } int id = getContext().getResources().getIdentifier(card.category, "string", getContext().getPackageName()); holder.category.setText(getContext().getResources().getString(id)); }else { holder.category.setVisibility(View.GONE); } holder.tagline.setText(card.tagline); holder.favorite.setChecked(card.favorite); holder.favorite.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { card.favorite = ((CheckBox) v).isChecked(); card.save(); } }); return view; } static class ViewHolder { @InjectView(R.id.logo) ImageView logo; @InjectView(R.id.name) TextView name; @InjectView(R.id.category) TextView category; @InjectView(R.id.tagline) TextView tagline; @InjectView(R.id.favorite) CheckBox favorite; public ViewHolder(View view) { ButterKnife.inject(this, view); } } 

    }

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.