Diferentes diseños de filas en ListView

Esta publicación está relacionada con este ViewHolder no funciona . En esa publicación, estaba siguiendo un tutorial sobre cómo usar ViewHolder en un ListView . Lo que quiero ahora es tener el último elemento en un ListView para tener un diseño diferente al rest. Aquí está mi código:

 int lastpos = mList.size()-1; System.out.println("position: "+position+" mlist: "+lastpos); if(position==lastpos){ view = vi.inflate(R.layout.list_item_record, null); holder.textView = (TextView)view.findViewById(R.id.record_view); }else{ view = vi.inflate(R.layout.list_item_bn, null); holder.textView = (TextView)view.findViewById(R.id.tv_name); } view.setTag(holder); 

Acabo de obtener el tamaño ListView menos 1 y tengo una condición que comprueba si la posición actual es igual al último elemento. Sin embargo, este código establece el diseño del último elemento igual que el rest. getView completo del método getView :

 private class CustomListAdapter extends ArrayAdapter { private ArrayList mList; private Context mContext; public CustomListAdapter(Context context, int textViewResourceId, ArrayList list) { super(context, textViewResourceId, list); this.mList = list; this.mContext = context; } public View getView(final int position, View convertView, ViewGroup parent) { View view = convertView; final ToggleButton tb; if (view == null) { ViewHolder holder = new ViewHolder(); LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); int lastpos = mList.size()-1; System.out.println("position: "+position+" mlist: "+lastpos); if(position==lastpos){ view = vi.inflate(R.layout.list_item_record, null); holder.textView = (TextView)view.findViewById(R.id.record_view); }else{ view = vi.inflate(R.layout.list_item_bn, null); holder.textView = (TextView)view.findViewById(R.id.tv_name); } view.setTag(holder); } final ItemsDisplay listItem = (ItemsDisplay) mList.get(position); if (listItem != null) { ViewHolder holder1 = (ViewHolder)view.getTag(); holder1.textView.setText(listItem.getTag()); view.setOnClickListener(new OnClickListener() { public void onClick(View arg0) { //--clickOnListItem Toast.makeText(getBaseContext(), "Button is "+position+" "+listItem.getTag(), Toast.LENGTH_LONG).show(); } }); tb = (ToggleButton) view.findViewById(R.id.toggleButton); tb.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if(tb.isChecked()){ Toast.makeText(getBaseContext(), "Button is "+position+" checked:"+tb.isChecked()+" "+listItem.getTag(), Toast.LENGTH_LONG).show(); }else{ Toast.makeText(getBaseContext(), "Button is "+position+" checked:"+tb.isChecked()+" "+listItem.getTag(), Toast.LENGTH_LONG).show(); } } }); } return view; } } 

¿Alguien podría ayudarme con esto?

Implemente getItemViewType() y getViewTypeCount() para su adaptador:

 @Override public int getViewTypeCount() { return 2; //return 2, you have two types that the getView() method will return, normal(0) and for the last row(1) } 

y:

 @Override public int getItemViewType(int position) { return (position == this.getCount() - 1) ? 1 : 0; //if we are at the last position then return 1, for any other position return 0 } 

Luego, en el método getView() averigüe qué tipo de vista para inflar:

 public View getView(final int position, View convertView, ViewGroup parent) { View view = convertView; int theType = getItemViewType(position); if (view == null) { ViewHolder holder = new ViewHolder(); LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (theType == 0) { // inflate the ordinary row view = vi.inflate(R.layout.list_item_bn, null); holder.textView = (TextView)view.findViewById(R.id.tv_name); } else if (theType == 1){ // inflate the row for the last position view = vi.inflate(R.layout.list_item_record, null); holder.textView = (TextView)view.findViewById(R.id.record_view); } view.setTag(holder); } //other stuff here, keep in mind that you have a different layout for your last position so double check what are trying to initialize } 

El ejemplo de los comentarios: http://pastebin.com/gn65240B (o https://gist.github.com/2641914 )

El problema es que una vez que ha inflado la vista, puede reutilizarse muchas veces en cualquier posición. Sugeriría el siguiente enfoque: se inflan todos los artículos menos el último (incluido el titular de la vista), pero para el último elemento se tiene la referencia como un campo de CustomListAdapter y se devuelve cada vez que se solicita el último elemento:

 private class CustomListAdapter extends ArrayAdapter { ... private View mLastItem; public View getView(final int position, View convertView, ViewGroup parent) { View view = convertView; ... int lastpos = mList.size()-1; if (view == null) { ViewHolder holder = new ViewHolder(); LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (position == lastpos) { view = vi.inflate(R.layout.list_item_record, null); holder.textView = (TextView)view.findViewById(R.id.record_view); mLastItem = view; } else { view = vi.inflate(R.layout.list_item_bn, null); holder.textView = (TextView)view.findViewById(R.id.tv_name); } view.setTag(holder); } if (position == lastpos) { ... // Update the last item here return mLastItem; } ... } }