Q:

Viewpager with gridview invalid index error

I have a viewpager which has multiple pages containing gridviews which are limited to a pre defined number of items.
The gridviews use a custom adaptor which for each page shows a predefined number of items from a json list, each page continues from where the last page left of in terms of items:
The issue i have is that once i click on an item and then press back to get to my list, clicking on another item returns an invalid index error:
my complete code below:
package com.guessthegame;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.viewpagerindicator.LinePageIndicator;
import android.os.Bundle;
import android.os.Parcelable;
import android.app.Activity;
import android.content.Intent;
import android.support.v4.app.NavUtils;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

public class GamesList extends Activity {

    static String file, name, desc, img = "";
    GameListAdaptor adaptor;
    GridView listViewGames;
    static TextView Tname;
    static TextView Tdesc;
    static TextView Tcount;
    ViewPager myPager;
    int perPage = 12;
    int gamesCnt = 0;
    int pagesNo = 1;
    int currentPage = 0;

    private class MyPagerAdapter extends PagerAdapter {
        public int getCount() {

            pagesNo = (int) Math.ceil(((float) gamesCnt / (float) perPage));

            return (pagesNo > 1 ? pagesNo  : 1 );
        }

        public Object instantiateItem(View collection, int position) {

            LayoutInflater inflater = (LayoutInflater) collection.getContext().getSystemService(getBaseContext().LAYOUT_INFLATER_SERVICE);

            View view = inflater.inflate(R.layout.activity_games_list, null);
            ((ViewPager) collection).addView(view, 0);

            adaptor = new GameListAdaptor(getBaseContext(),R.layout.game, loadGames(position+1));

            listViewGames = (GridView) view.findViewById(R.id.games);

            listViewGames.setClickable(true);

            listViewGames.setOnItemClickListener(new OnItemClickListener() {

               @Override
               public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    // TODO Auto-generated method stub
                  // if(position <= loadGames(position+1).size()) {

                       Games games = adaptor.getItem(position);

                        Intent intent = new Intent(GamesList.this, Game.class);

                        intent.putExtra("FILE", file);
                        intent.putExtra("IMG", games.img);
                        intent.putExtra("HINT", games.hint);
                        intent.putExtra("SOUND", games.sound);
                        intent.putExtra("ANSWER", games.answer);
                        intent.putExtra("CLOSE", games.close);

                        startActivity(intent);
                  // }
                }

            });

            listViewGames.setAdapter(adaptor);

            adaptor.setNotifyOnChange(true);

            return view;

            }
            @Override
            public void destroyItem(View arg0, int arg1, Object arg2) {
                ((ViewPager) arg0).removeView((View) arg2);
            }
            @Override
            public boolean isViewFromObject(View arg0, Object arg1) {
                return arg0 == ((View) arg1);
            }
            @Override
            public Parcelable saveState() {
                return null;
            }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_games_page);

        // Show the Up button in the action bar.
        //getActionBar().setDisplayHomeAsUpEnabled(true);

        Bundle extras = getIntent().getExtras();

        if(extras != null) {
            file    = extras.getString("FILE");
            name    = extras.getString("NAME");
            desc    = extras.getString("DESC");
            img     = extras.getString("IMG");
        }

        if(file != "") {

            gamesCnt = MainActivity.prefs.getInt(file+"_cnt", 0);

            MyPagerAdapter adapterP = new MyPagerAdapter();
            myPager = (ViewPager) findViewById(R.id.myfivepanelpager);
            myPager.setAdapter(adapterP);
            //myPager.setCurrentItem(0);

            //Bind the title indicator to the adapter
            LinePageIndicator titleIndicator = (LinePageIndicator)findViewById(R.id.indicator);
            titleIndicator.setViewPager(myPager);
            //new LoadJsonTask().execute();

        }

    }

    @Override
    public void onResume() { 
        // After a pause OR at startup
        super.onResume();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        //getMenuInflater().inflate(R.menu.activity_games_list, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private ArrayList<Games> loadGames(int position) {
        ArrayList<Games> games = new ArrayList<Games>();

        String jsonString = null;

        InputStream in;
        try {
            in = this.getAssets().open(file);

            int size = in.available();

            byte[] buffer = new byte[size];
            in.read(buffer);
            in.close();

            jsonString = new String(buffer);

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {

            JSONObject jsonObj = new JSONObject(jsonString);

            JSONArray gamesArr = jsonObj.getJSONArray("games");

            int gamesCnt = gamesArr.length();

            int startNo = (position == 1 ? 0 : (position-1) * perPage + 1);
            int endNo   = ((startNo+perPage) > gamesCnt ? gamesCnt : (startNo+perPage));

            Log.i("info",position + " - " + startNo + " <= " + endNo + " | " + gamesArr.length());

            for(int currentNo = startNo; currentNo < endNo; currentNo++) {

                JSONObject j = gamesArr.getJSONObject(currentNo);

                Games game= new Games();

                game.img    = (j.getString("img") != "" ? j.getString("img") : "" );
                game.hint   = (j.getString("hint") != "" ? j.getString("hint") : "" );
                game.sound  = (j.getString("sound") != "" ? j.getString("sound") : "" );
                game.answer = (j.getString("answer") != "" ? j.getString("answer") : "" );
                game.close  = (j.getString("close") != "" ? j.getString("close") : "" );

                games.add(game);

            }

        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       

        return games;

    }

}

Logcat:
    03-19 17:51:31.838: E/AndroidRuntime(14573): FATAL EXCEPTION: main
    03-19 17:51:31.838: E/AndroidRuntime(14573): java.lang.IndexOutOfBoundsException: Invalid index 9, size is 0
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at java.util.ArrayList.get(ArrayList.java:304)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:337)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at com.guessthegame.GamesList$MyPagerAdapter$1.onItemClick(GamesList.java:71)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at android.widget.AdapterView.performItemClick(AdapterView.java:298)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at android.widget.AbsListView.performItemClick(AbsListView.java:1100)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at android.widget.AbsListView$PerformClick.run(AbsListView.java:2749)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at android.widget.AbsListView$1.run(AbsListView.java:3423)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at android.os.Handler.handleCallback(Handler.java:725)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at android.os.Handler.dispatchMessage(Handler.java:92)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at android.os.Looper.loop(Looper.java:137)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at android.app.ActivityThread.main(ActivityThread.java:5041)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at java.lang.reflect.Method.invokeNative(Native Method)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at java.lang.reflect.Method.invoke(Method.java:511)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
    03-19 17:51:31.838: E/AndroidRuntime(14573):    at dalvik.system.NativeStart.main(Native Method)

I assume its because im adding a gridview to each page and the onclick listener dosnt know which view to get the position from. How do i get around this?

A:

Fixed by removing the onitemclicklistner and adding onclicklistner into my list adaptor instead.

