Android: updating an item in a ListView that survives scrolling

81 Views Asked by At

Given a ListActivity with a ListView and the requirement to change an item based on user input, what is the way to make the change so that the change survives scrolling?

Currently the application uses a ResourceCursorAdapter populated by a Cursor from a database. When the user long-clicks an item, an ImageView on that item is toggled between View.VISIBLE and View.GONE. Also, the flag in the database supporting the view state is managed.

But when that item scrolls off the screen, then back onto the screen, the item is represented without the recent change. In other words, if I make the ImageView visible with a long-click, it shows fine. But when I scroll away from that item, then scroll back to it, it is no longer visible.

My current solution (which I think is wrong) is to save the scroll position, refresh the entire list from the database, then position to the proper location again.

I imagine there's some way to tell some Androidy thing to put the new visibility state into it's cache, but I can't find it. I've tried setScrollingCacheEnabled(false), and some other cache's false, but none of those seemed to make a difference. I tried to figure out how to make Android realize it's 'dirty', but all I found was to query if it isDirty(). I also tried ResourceCursorAdapter.notifyDataSetChanged(), and that made the setVisibility() call ineffective on visibility. I also tried invalidate() and invalidateViews() in various places. It could be one of these would work if applied to the correct object in the correct sequence (before or after the visibility was changed).

1

There are 1 best solutions below

3
On

Override getView method in ListView and try to use it like this :

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder; // view lookup cache stored in tag
        if (convertView == null) {
            viewHolder = new ViewHolder();
            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(R.layout.your.layout, parent, false);
            viewHolder.img = (TextView) convertView.findViewById(R.id.img);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        if (condition) {
            viewHolder.img.setVisibility(VIEW.VISIBLE);
        else { 
           viewHolder.img.setVisibility(VIEW.GONE);
        }

        // Return the completed view to render on screen
        return convertView;
    }