Cómo implementar 2 tipos diferentes de seperators (es decir, encabezados) en una clase de adaptador ListView

Estoy llamando al adaptador por este conjunto de códigos

mAdapter = new MyCustomAdapter(getActivity()); mAdapter.addSeparatorItem(new ContentWrapper(q.get(0).getA_name(),null)); mAdapter.addItem(new ContentWrapper(q.get(0).getAS_name(), q.get(0).getDesc_art())); 

Considere este código:

 private class MyCustomAdapter extends BaseAdapter { private static final int TYPE_ITEM = 0; private static final int TYPE_SEPARATOR = 1; private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1; private ArrayList<ContentWrapper> mData = new ArrayList<ContentWrapper>(); private LayoutInflater mInflater; private TreeSet<Integer> mSeparatorsSet = new TreeSet<Integer>(); public MyCustomAdapter(Context context) { mInflater = LayoutInflater.from(context); } public void addItem(ContentWrapper value) { mData.add(value); notifyDataSetChanged(); } public void addSeparatorItem(ContentWrapper value) { mData.add(value); // save separator position mSeparatorsSet.add(mData.size() - 1); notifyDataSetChanged(); } public ContentWrapper getItem(int position) { return mData.get(position); } @Override public int getItemViewType(int position) { return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM; } @Override public int getViewTypeCount() { return TYPE_MAX_COUNT; } public int getCount() { return mData.size(); } public long getItemId(int position) { Log.v("getItemId Position", ""+position); return position; } public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder = null; int type = getItemViewType(position); if (convertView == null) { holder = new ViewHolder(); switch (type) { case TYPE_ITEM: convertView = mInflater.inflate(R.layout.white, null); holder.textView = (TextView)convertView.findViewById(R.id.text); break; case TYPE_SEPARATOR: convertView = mInflater.inflate(R.layout.black, null); holder.textView = (TextView)convertView.findViewById(R.id.textSeparator); count++; break; } convertView.setTag(holder); } else { holder = (ViewHolder)convertView.getTag(); } holder.textView.setText(mData.get(position).getItem()); if (type == TYPE_ITEM) { holder.textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setIcon(R.drawable.ic_launcher); final String title = mData.get(position).getItem(); builder.setTitle(title); builder.setMessage(mData.get(position).getItemDescription()); builder.setCancelable(false); builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); AlertDialog alertDialog = builder.create(); alertDialog.setOnShowListener(new DialogInterface.OnShowListener() { @Override public void onShow(DialogInterface dialog) { AlertDialog alertDialog = (AlertDialog) dialog; ViewGroup viewGroup = (ViewGroup) alertDialog.getWindow() .getDecorView(); TextView textView = findTextViewWithTitle(viewGroup, title); if (textView != null) { textView.setEllipsize(null); textView.setMaxHeight((int) (100 * alertDialog.getContext().getResources().getDisplayMetrics().density)); textView.setMovementMethod(new ScrollingMovementMethod()); } } }); alertDialog.show(); } private TextView findTextViewWithTitle(ViewGroup viewGroup, String title) { for (int i = 0, N = viewGroup.getChildCount(); i < N; i++) { View child = viewGroup.getChildAt(i); if (child instanceof TextView) { TextView textView = (TextView) child; if (textView.getText().equals(title)) { return textView; } } else if (child instanceof ViewGroup) { ViewGroup vGroup = (ViewGroup) child; return findTextViewWithTitle(vGroup, title); } } return null; } }); } else { holder.textView.setOnClickListener(null); } return convertView; } } public static class ViewHolder { public TextView textView; } public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub return false; } 

Este código sólo muestra la descripción del elemento seleccionado (aquí TYPE_ITEM ) en un AlertDialog.

Como se puede ver TYPE_SEPERATOR ha desactivado onClick () y quiero añadir uno más TYPE_SEPERATOR_GRAY (dejar de gray.xml ) ser el otro tipo seperator con disabled onClick ().

¿Necesito agregar un método más similar a addSeparatorItem(ContentWrapper value) como addSeparatorItemGray(ContentWrapper value) . Sé que tengo que añadir un caso más en el cambio de getView () para inflar el gray.xml

¿O qué más debo añadir / modificar?

EDIT: ContentWrapper contiene elementos de texto con su descripción. Implementé ContentWrapper para asignar cada TYPE_ITEM con una descripción

 public class ContentWrapper { private String mItem, mItemDescription; public ContentWrapper(String item, String itemDescription) { mItem = item; mItemDescription = itemDescription; } public String getItem() { return mItem; } public String getItemDescription() { return mItemDescription; } } 

MAdapter es del tipo MyCustomAdapter.

Las primeras 3-4 líneas de mi pregunta dicen que addSeparatorItem no tiene ninguna descripción así que pasó null en el segundo argumento y addItem tiene texto, descripción.

Quiero agregar el otro TYPE_GRAY_SEPARATOR, en algunas posiciones especificadas en la lista manualmente como

  mAdapter.addSeparatorItemGray("HI after 1st view"); mAdapter.addSeparatorItemGray("HI after 23rd view"); mAdapter.addSeparatorItemGray("HI after 45 view"); 

El método getViewType debe devolver 3 (elemento de lista + separador + separador de gris). Por lo tanto, establezca TYPE_MAX_COUNT en 3.

 private static final int TYPE_GRAY_SEPARATOR = 2; private static final int TYPE_MAX_COUNT = TYPE_GRAY_SEPARATOR + 1; 

Estructura de datos para mantener posiciones separadoras grises:

 private TreeSet<Integer> mGraySeparatorsSet = new TreeSet<Integer>(); 

Método para agregar el separador gris.

 public void addGraySeparatorItem(ContentWrapper value) { mData.add(value); // save separator position mGraySeparatorsSet.add(mData.size() - 1); notifyDataSetChanged(); } 

El método getItemViewType debe devolver la vista apropiada en función de la posición.

 @Override public int getItemViewType(int position) { int viewType = TYPE_ITEM; if(mSeparatorSet.contains(position)) viewType = TYPE_SEPARATOR; else if(mGraySeparatorSet.contains(position)) { viewType = TYPE_GRAY_SEPARATOR; } return viewType; } 

El método getView debe manejar TYPE_GRAY_SEPARATOR:

 public View getView(final int position, View convertView, ViewGroup parent) { // Existing code switch(type) { // Existing cases case TYPE_GRAY_SEPARATOR: // Inflate appropriate view break; } // Existing code } 

Piense en el separador extra como otro tipo de vista.
Por lo tanto, para ajustarse a su estilo de código, debe agregar otra Collection para estos separadores y agregar los métodos necesarios:

 private static final int TYPE_GRAY_SEPARATOR = 2; private TreeSet<Integer> mGraySeparatorsSet = new TreeSet<Integer>(); 

También actualice su método getViewTypeCount() , ya que tiene un tipo de vista más ahora.
Por último, agregue otro if else verifique su método getView , comprobando este nuevo tipo de vista.


Por otra parte, echa un vistazo a la biblioteca StickyListHeaders , que maneja una gran cantidad de esta lógica para usted.

Primero, agrega otro tipo a getViewTypeCount y getItemViewType, como otros sugieren.

Sin embargo, usted lo hace incorrecto. No es necesario que haga clic en los elementos de la lista. Esta es una tarea de ListView para detectar clics y disparar OnItemClickListener cuando se hace clic en el elemento. Así que puede quitar todas las llamadas setOnClickListener.

Para crear separadores en ListView, necesita deshabilitar algunos elementos. Para ello, existen estas funciones:

  • BaseAdapter.areAllItemsEnabled () – devuelve false
  • IsEnabled (int position) – devuelve false para elementos que son separadores

Además, no es necesario usar Set <> para marcar separadores. Basta con buscar su lista de fuentes de entradas con la posición , y volver a que los separadores están deshabilitados, los elementos normales están habilitados.

  • Detección de la dirección de desplazamiento en el adaptador (arriba / abajo)
  • ListView en ArrayAdapter orden se mezcla cuando se desplaza
  • Android ListView áreas parciales presionables
  • ¿Cómo agrego un onclicklistener a un botón dentro de un adaptador listview?
  • ¿Hay una manera de desactivar / editar el desvanecimiento que una vista de lista tiene en sus bordes?
  • Rellene Listview desde el origen de la matriz de cadenas, con un String ArrayAdapter
  • ¿Cómo puedo quitar el botón de borrar en searchbox de listview?
  • Cómo cambiar el modo de selección ListView de solo a múltiple al hacer clic en evento en android?
  • Cómo configurar el tamaño y el diseño en onSizeChanged?
  • Android Drawer Layout está mostrando contenido de fragmentos
  • Onclicklistner no funciona en el listview de fragmentos
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.