问题
I have a ListView whose items can be deleted by swiping them. When an item is swiped, its database row gets deleted, as well as its object in the adapter's data set, and notifyDataSetChanged() is called as well. The problem is, these items have varying heights - one can be a one-liner, the second can have four lines. So when I have some items on the list, let's say:
1.One line
2.Two lines
3.Three lines
4.One line
And the second one is deleted, the third one goes in its place (as expected), but gets cut off to two lines. And when the third one is deleted, the fourth item's height is increased to match the deleted item's.
I found a way to fix that, however it's probably a wrong one - it creates a new view even if a convertView is not null.
I wonder if this can be achieved in another, recycling-friendly way.
Current adapter code:
public class CounterItemAdapter extends BaseAdapter{
private Activity activity;
private ArrayList<CounterItem> data;
private SQLiteOpenHelper helper;
private static LayoutInflater inflater = null;
public CounterItemAdapter(Activity activity, ArrayList<CounterItem> data, SQLiteOpenHelper helper) {
this.activity = activity;
this.data = data;
this.helper = helper;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return data.size();
}
@Override
public CounterItem getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return getItem(position).getId();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
//if(convertView == null)
view = inflater.inflate(R.layout.counter_list_item, null);
TextView nameView = (TextView)view.findViewById(R.id.nameView);
//other, unrelated views were here
final CounterItem counterItem;
counterItem = getItem(position);
nameView.setText(counterItem.getName());
return view;
}
}
回答1:
Okay, i've found a solution.
Added int lastValidPosition = -1;
in the adapter, then adapter.lastValidPosition = position-1
in the deletion callback method, before adapter.notifyDataSetChanged();
, and in the getView() method of the adapter i've changed
//if(convertView == null)
view = inflater.inflate(R.layout.counter_list_item, null);
to
if(lastValidPosition < position | convertView == null){
view = inflater.inflate(R.layout.counter_list_item, null);
lastValidPosition = position;
}
and it works perfectly.
来源:https://stackoverflow.com/questions/17910120/listview-item-deletion-changes-item-heights