0

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).

Dale
  • 4,421
  • 2
  • 37
  • 68
  • 1
    Are you changing data when user long clicks on any row? You should change Data model so that the row will be inflated according to new Data model class next time. ... – Kushal Aug 30 '16 at 10:34
  • The preferred method for `ListView` functionality is now `RecylcerView`. The answer here contains details for managing a list that manages user altered data in a list implemented with the preferred method: http://stackoverflow.com/a/40568269/897007 – Dale Nov 13 '16 at 15:36

1 Answers1

0

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;
    }
mayosk
  • 588
  • 2
  • 12
  • Thanks for the suggestion, but I'm not sure how to work that out since I'm currently getting my `ListView` by calling `getListView()` from my class that extends `ListActivity`. That leaves me with a question of how I could override the `ListView` that is supplied by the `ListActivity`. – Dale Aug 23 '16 at 23:12
  • 1
    Are you sure that you need to use ListActivity? Just extend AppCompatActivity and add ListView to the content. – mayosk Aug 24 '16 at 07:55
  • 1
    @Dale : Override `getView()` in Adapter class not in `ListView` subclass – Kushal Aug 30 '16 at 10:29