Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy is changing where layout parameters are set solving my "OnClickListener not working for first item in GridView" issue?
    primarykey
    data
    text
    <p>I'm using a GridView to show some images and I had a problem, as the onClickListener wasn't working for the first image. I found some other questions here at SO with the same problem, but I don't like their "correct answers", as most of them take the same approach of:</p> <ul> <li><a href="https://stackoverflow.com/questions/12746433/onclicklistener-not-working-for-first-item-in-gridview-inside-viewpager">OnClickListener not working for first item in GridView inside ViewPager</a></li> </ul> <p>Basically, instantiating the view every time getview is called. This is awful for performance and they will probably face out-of-memory issues in many devices.</p> <p>In my case, I display in the GridView the images located inside a sub-folder in the assets folder.</p> <p>My original code with the "first item" issue (actually, my original code implemented the viewholder pattern, but this one is a bit simpler and faces the same issue):</p> <pre><code> @Override public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView; if (convertView == null) { imageView = new ImageView(_activity); } else { imageView = (ImageView) convertView; } // get screen dimensions AssetManager assetManager = _activity.getAssets(); InputStream assetIn = null; try { assetIn = assetManager.open(_assets_subdir + File.separator + _filePaths.get(position)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } Bitmap image = BitmapFactory.decodeStream(assetIn); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setLayoutParams(new GridView.LayoutParams(imageWidth, imageWidth)); imageView.setImageBitmap(image); // image view click listener imageView.setOnClickListener(new OnImageClickListener(position)); return imageView; } </code></pre> <p>My final code solving the issue:</p> <pre><code> @Override public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView; if (convertView == null) { imageView = new ImageView(_activity); imageView.setLayoutParams(new GridView.LayoutParams(imageWidth, imageWidth)); } else { imageView = (ImageView) convertView; } // get screen dimensions AssetManager assetManager = _activity.getAssets(); InputStream assetIn = null; try { assetIn = assetManager.open(_assets_subdir + File.separator + _filePaths.get(position)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } Bitmap image = BitmapFactory.decodeStream(assetIn); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setImageBitmap(image); // image view click listener imageView.setOnClickListener(new OnImageClickListener(position)); return imageView; } </code></pre> <p>The issue was solved moving the code <code>imageView.setLayoutParams(new GridView.LayoutParams(imageWidth, imageWidth));</code>. </p> <p>But why? I'm not sure.</p> <p>I read somewhere (in SO) that it could be happening because of trying to access a view that has not been inflated yet, and the user recommended using <code>getViewTreeObserver()</code>, but I tried that approach and couldn't fix the problem.</p> <p>So, I decided to trial-and-error the code to see where to bottleneck could be and found the given solution. </p> <p>Anyone knows why is this solving the problem?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. COThis could be of some help [link] [1]: http://stackoverflow.com/questions/11778228/onclicklistener-not-working-for-first-item-in-gridview
      singulars
    2. COThanks @anish but that is an example of the (IMHO) wrong fixes I mention in the question. His fix is, literally, "ended up fixing it by just instatiating the holder in every pass, instead of getting it by tag(which is better for performance, but oh well)." `getView()`can be called multiple times and he is bypassing the usefulness of `convertView` by inflating the layout and calling `findViewById` two times EVERY time `getView()` is called. Using images in the GridView will probably lead to OutOfMemory crashes.
      singulars
    3. COThe likely reason adding LayoutParams is resolving your problem, is that it's triggering another layout pass. This seems to suggest that your view is being reused elsewhere, and its OnClickListener is being replaced. I recall having run into this odd behavior myself, but don't quite remember how I worked around it. I'll see if I can figure out which project it was related to.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload