You should not override getViewTypeCount() and getItemViewType() if all items in the list are uniform or at least return them 1 and 0 respectively.
Redefining them the way you did, first of all, you prohibit the ListView relational processing mechanism, and secondly, it probably leads to the collapse described by you, because when you delete an item from the middle of the list, the types from the views change after deletion .
UPDATE: Actually, this is what happens: ListView calls getViewTypeCount() on the adapter only in setAdapter() and creates an internal array of this size. Therefore, if you add views later, and your getItemViewType() returns an index greater than or equal to this size, you will get an ArrayIndexOutOfBoundsException .
UPDATE 2:. If you need a list extension just use the ExpandableListView .
UPDATE 3: Well, I will explain as much as possible.
There is no reason to open screen views. ListView designed to be recycled and inhibited, it is not needed in 99.9% of cases, and your case does not drop to 0.01%.
Your adapter should remember all the details and populate the reappearing views when scrolling through the ListView.
In your case, you have two types of views - open and closed, so getViewTypeCount() should return 2, and getItemViewType() should return 0 or 1 depending on whether the view is closed or open.
In getView() , if convertView is null, you should create it depending on what getItemViewType() returns for this position. And if it's not null, you are guaranteed that this is one of the views that you created earlier for the same type.
And here is the point of failure that occurs if your getItemViewType() returns arbitrary large numbers (I mean the sources for API 19):