Различные раскладки строк в 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
и имею условие, которое проверяет, соответствует ли текущая позиция последнему элементу. Однако этот код устанавливает последний макет элемента так же, как и остальные. 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;
}
}
Может ли кто-нибудь помочь мне с этим?
Ответы
Ответ 1
Внесите 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)
Ответ 2
Проблема заключается в том, что после того, как вы раздули представление, его можно многократно использовать в любой позиции. Я бы предложил следующий подход: вы надуваете все, кроме последнего, как обычно (включая держатель вида), но для последнего элемента вы сохраняете ссылку как поле 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;
}
...
}
}