2

I have written a custom adapter for a gridview. Each item in grid view has other childs views. One of them is a textView, which has implemented a click listener.

When the user clicks on the TextView, I show a Toast which shows the position of the item in gridView.

Now coming to the problem:

I assign the "position" returned by getView() as a tag to the TextView every time the getView() is called. When I scroll the "position" provided by getView() is the correct value but as soon as the scrolling stops, the position provided by getView() becomes 0, which shouldn't be zero in the first place unless I am at the top of the grid view. However the value saved in the TextView tag is always the correct value. Why is that?

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder viewHolder;

        if(convertView == null){
            convertView = mLayoutIflater.inflate(R.layout.grid_item, null);
            viewHolder = new ViewHolder();

            …..
            viewHolder.playButton.setOnClickListener(new View.OnClickListener() {
                 @Override
                    public void onClick(View v) {
                         Log.e(“test”, "myPos: "+ (Integer) viewHolder.mTextView.getTag()); // always returns correct position value

                        }
                    });

            convertView.setTag(viewHolder);
        }
        else
            viewHolder = (ViewHolder) convertView.getTag();


        Log.e(“test”, "GETVIEW: "+ position); // position is zero when scrolling stops & correct value when scrolling
        viewHolder.mTextView.setTag(position);

        return convertView;
    }

Best Regards

user2498079
  • 2,872
  • 8
  • 32
  • 60

4 Answers4

1

Modify the code like this,

 @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            final ViewHolder viewHolder;

            if(convertView == null){
                convertView = mLayoutIflater.inflate(R.layout.grid_item, null);
                viewHolder = new ViewHolder();

                …..


                convertView.setTag(viewHolder);
            }
            else
                viewHolder = (ViewHolder) convertView.getTag();


            Log.e(“test”, "GETVIEW: "+ position); // position is zero when scrolling stops & correct value when scrolling
            viewHolder.mTextView.setTag(position);

viewHolder.playButton.setOnClickListener(new View.OnClickListener() {
                     @Override
                        public void onClick(View v) {
                             Log.e(“test”, "myPos: "+ (Integer) viewHolder.mTextView.getTag()); // always returns correct position value

                            }
                        });

            return convertView;
        }
Krish
  • 3,860
  • 1
  • 19
  • 32
0

Try this.

 convertView = mLayoutIflater.inflate(R.layout.grid_item, parent, false);
Simar
  • 600
  • 4
  • 17
0

An AdapterView can call getView() on its Adapter quite seemingly arbitrarily. There is no guaranteed order or timing for doing so. It's irrelevant that the last position it calls the method for might be the 0 position when scrolling is completed. Caching the passed position value with the corresponding View (or child thereof) is the correct way to keep track of it. The last position for which getView() is called isn't going to tell you anything relevant to how your AdapterView should behave, and you shouldn't rely on it for such.

Mike M.
  • 38,532
  • 8
  • 99
  • 95
  • But the last time getView() get called, I am still caching/saving the position in the childviews, why doesn't it effect the cached values in the child views? I can't understand that. – user2498079 Jan 10 '15 at 16:22
  • @user2498079 It would affect those cached values, but they're the values for the corresponding View. If the position passed into the method is `0`, then the View passed into the method is the `0` View. It doesn't necessarily mean that that View is currently visible on-screen. – Mike M. Jan 10 '15 at 16:28
0

The adapter is not really a place to define onClickListener. Try using onItemClickListener() for the GridView in your main Activity or wherever it's been defined. That's the easier way and how it should be done. Always prefer the recommended practices for Android rather than experimenting in the classes.

huskygrad
  • 1,257
  • 1
  • 10
  • 21