Различные раскладки строк в ListView

Этот пост связан с этим ViewHolder не работает . На этом посту я следил за учебником по использованию ViewHolder в ListView . Теперь я хочу, чтобы последний элемент в ListView имел другой макет, чем остальные. Вот мой код:

 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); 

Я просто получаю размер ListView минус 1 и имею условие, которое проверяет текущую позицию if, равную последнему элементу. Однако этот код устанавливает макет последнего элемента так же, как и остальные. getView метод 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; } } 

Может ли кто-нибудь помочь мне в этом?

Solutions Collecting From Web of "Различные раскладки строк в ListView"

getItemViewType() и getViewTypeCount() для вашего адаптера:

 @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) } 

а также:

 @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 } 

Затем в getView() выясните, какой тип представления надуть:

 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 } 

Пример из комментариев: http://pastebin.com/gn65240B (или https://gist.github.com/2641914 )

Проблема в том, что после того, как вы завысили представление, его можно многократно использовать в любой позиции. Я бы предложил следующий подход: вы раздуваете все, кроме последнего элемента, как обычно (включая держатель вида), но для последнего элемента вы держите ссылку как поле CustomListAdapter и возвращаете ее каждый раз, когда запрашивается последний элемент:

 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; } ... } }