Fork me on Github

Shivam Verma
    Blog     Portfolio     About Me / Contact     Feed

Hiding a list item from an Android ListView without removing it from the data source.

Ideally when I have to remove a list item from a listview, I’d remove the data object from the collection which the adapter uses and then do a adapter.notifyDataSetChanged() call which’ll redraw the list view.

Consider an adapter which uses an array list of Strings.

public class SampleAdapter extends BaseAdapter {
    Activity activity;
    ArrayList<String> listItems;
    public SampleAdapter(Activity activity, ArrayList<String> listItems) {
        this.activity = activtity;
        this.listItems = listItems;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup arg2) {
        String testString = listItems.get(position);
    }    
}

Now, to delete an item from the ListView,

listItems.remove(position);
adapter.notifyDataSetChanged();

But this approach also removes the item from the listItems ArrayList.

###What if I do not want to remove the item from the collection and prevent it from displaying in the ListView?

A couple of solutions suggest setting the height of the list item to 0 or to set the visibility of the view to GONE but this does not solve the problem effectively because the list item separator still shows up in the list view making it look clumsy.

To tackle this problem, I’ll use another ArrayList which stores the positions of items in the listItems ArrayList which shouldn’t show up in the ListView.

Let’s define another ArrayList of Integers which can store these positions, as an instance variable, and add the logic of hiding a particular view in thegetView() method of the adapter.

Also, check out the getCount() method which should return the correct size of the number of items in the ListView.

public class SampleAdapter extends BaseAdapter {
    Activity activity;
    ArrayList<String> listItems;
    ArrayList<Integer> hiddenPositions = new ArrayList<>();

    public SampleAdapter(Activity activity, ArrayList<String> listItems) {
        this.activity = activtity;
        this.listItems = listItems;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup arg2) {
        // The following small snippet of code ensures 
        // that we skip data from all the hidden positions 
        // and use the updated position to fetch the 
        // correct data from the listItems ArrayList. 
        for(Integer hiddenIndex : hiddenPositions) {
            if(hiddenIndex <= position) {
                position = position + 1;
            }
        }
        String testString = listItems.get(position);
    }    

    @Override
    public int getCount() {
        return listItems.size() - hiddenPositions.size();
    }
}

Now, whenever I need to hide an item from appearing in the ListView, I add the position value to the hiddenPositions ArrayList and do a notifyDataSetChanged() call.

To show hidden items again, just remove the position value from the hiddenPositions ArrayList and call notifyDataSetChanged() .

Cheers!

comments powered by Disqus