ListView item deletion changes the project height
I have a ListView
whose items can be deleted by swiping. When an item is flashed, its database rows are deleted, as well as its objects in the adapter dataset, and notifyDataSetChanged()
is also called. The problem is, these items have different heights – one can be one line, the second can have four rows. So when I have some items on the list, let’s say:
1. One line
2. Two lines
3. Three lines
4. One line
The second is removed and the third replaces it (as expected), but truncated to two lines. When the third item is deleted, the height of the fourth item increases to match the deleted item.
I found a solution to the problem, but it may be wrong – it creates a new View even if the convertView is not empty.
I wonder if this can be achieved in another way that favors recycling.
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;
}
}
Solution
Ok, I found the solution.
Added int lastValidPosition = -1;
in the adapter, then adapter.lastValidPosition = position-1
In the delete callback method, in adapter.notifyDataSetChanged();
Before.
, and in the getView()
method of the adapter I have 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 well.