Java – ListView item deletion changes the project height

ListView item deletion changes the project height… here is a solution to the problem.

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.

Related Problems and Solutions