3

I have a GridView in which I want to always show 7 icons, and sometimes an additional icon depending on a request. In the beginning the additional icon is never shown. This is the structure:

0   1   2
3   4   5
6  [7]

All the icons fit into the screen so I don't need/have scroll. Each icon is composed by an image and a text.

For this, I have a CustomAdapter which extends BaseAdapter. I have overriden the getView method in which I set the text and the image for each icon.

public View getView(int position, View convertView, ViewGroup parent) {
    View v = null;

    if (convertView == null) {
        LayoutInflater li = ((Activity) context).getLayoutInflater();
        v = li.inflate(R.layout.icon, null);
    } else {
        v = convertView;
    }

    TextView tv = (TextView) v.findViewById(R.id.icon_textView);
    tv.setText(position);
    ImageView iv = (ImageView) v.findViewById(R.id.icon_ImageView);
    iv.setImageResource(imageResourcesArray[position]);

    if ((position == ADDITIONAL_ICON)) && !showAdditionalIcon) {
        v.setVisibility(View.INVISIBLE);
    }

    return v;
}

The imageResourcesArray[] is an array of integers with the image resources. The other functions and variables in the CustomAdapter are:

public static final int ADDITIONAL_ICON = 7;
private boolean showAdditionalIcon = false;

public showAdditionalIcon(){
    this.showAdditionalIcon = true;
    notifyDataSetChanged();
    // notifyDataSetInvalidated();
}

public hideAdditionalIcon(){
    this.showAdditionalIcon = false;
    notifyDataSetChanged();
    // notifyDataSetInvalidated();
}

Later on, I create and set the CustomAdapter to the GridView from a class which extends Activity (say ClassA):

    GridView grid = (GridView) findViewById(R.id.main_gridView);
    customAdapter = new CustomAdapter(this);
    grid.setAdapter(customAdapter);

My problem appears when after some calculations and requests to a server, I have to show the additional icon (number 7). So I call (from ClassA):

    customAdapter.showAdditionalIcon();

Now, the additional icon appears, but the first icon disappears... I have tried to use notifyDataSetInvalidated() and notifyDataSetChanged() but both had the same result.

Of course, I could generate a new CustomAdapter with the additional icon allowed, but I would preffer not to do it...

Thanks in advance.

jalv1039
  • 1,663
  • 3
  • 17
  • 21
  • 1
    v.setVisibility(View.INVISIBLE); instead of this try v.setVisibility(View.GONE); Secondly, when you need to show it view.setVisibility(View.VISIBLE); – Vinay Nov 11 '11 at 12:24
  • but if I do this you suggest, I should save the view of icon 7 in a variable, isn't it? Right now, I don't save any of the views, so the BaseAdapter should know when to update/regenerate all the icons. – jalv1039 Nov 11 '11 at 12:35
  • I finally did what you suggested. I removed the notifyDataSetInvalidated() and notifyDataSetChanged() calls and it works great. Thank you! – jalv1039 Nov 13 '11 at 11:12
  • Please check my answer it will be helpful. [1]: http://stackoverflow.com/questions/8933776/set-visibility-of-a-gridview-element/24429621#24429621 – Mukesh Parmar Jun 26 '14 at 13:08

1 Answers1

1

I'm not sure if this counts as an answer for you. Root of the problem seems to be the convertView we are using. I did not dig so deep into Android source, but I think there is no guarantee on how views are reused even it is obvious that all views are already visible and there should be no reuse behind the scenes.

What this means is that the view we linked to position 7 as we visualize this whole scenario is actually reused later at position 0. Since your code does not explicitly reset a view to be visible, the view will be reused with visibility set to INVISIBLE, thus the mystery of the disappearing first item.

Simplest solution should be as @Vinay suggest above, by explicitly setting to View.VISIBLE.

if ((position == ADDITIONAL_ICON))) {
    if (!showAdditionalIcon)
        v.setVisibility(View.INVISIBLE);
    else
        v.setVisibility(View.VISIBLE);
}

Hope this helps, but I'm really hoping some Android expert pops by to tell us more about how this whole thing of reusing old views actually works.

yjw
  • 3,394
  • 4
  • 20
  • 20
  • Yes, thank you both for the solutions. I realized that I don't need to call notifyDataSetInvalidated() or notifyDataSetChanged() since I am not changing anything, just showing it. Instead of that, I just keep in a variable the View for the icon 7 and when I need to show it I simply do what you both suggest. – jalv1039 Nov 13 '11 at 11:11