ExpandableListView中的IndexOutOfBoundException

时间:2014-07-12 06:39:01

标签: android expandablelistview

我发现了很多关于这个问题的问题,但我无法修复它。我花了一整天时间无法解决。我也重新检查了我的for循环

如果我有父母价值7,如果我点击第4位父母进行扩展,我再次点击第二位父母,其费用和工作正常。但如果我点击第5或第6或第7个家长我收到此错误..我不知道我的代码在哪里错了..

LogCat:

07-12 11:56:24.504: E/AndroidRuntime(3548): FATAL EXCEPTION: main
07-12 11:56:24.504: E/AndroidRuntime(3548): java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0
07-12 11:56:24.504: E/AndroidRuntime(3548):     at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at java.util.ArrayList.add(ArrayList.java:143)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at android.widget.ExpandableListConnector.expandGroup(ExpandableListConnector.java:685)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at android.widget.ExpandableListView.handleItemClick(ExpandableListView.java:562)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at android.widget.ExpandableListView.performItemClick(ExpandableListView.java:522)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:2812)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at android.widget.AbsListView$1.run(AbsListView.java:3571)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at android.os.Handler.handleCallback(Handler.java:725)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at android.os.Handler.dispatchMessage(Handler.java:92)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at android.os.Looper.loop(Looper.java:153)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at android.app.ActivityThread.main(ActivityThread.java:5297)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at java.lang.reflect.Method.invokeNative(Native Method)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at java.lang.reflect.Method.invoke(Method.java:511)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
07-12 11:56:24.504: E/AndroidRuntime(3548):     at dalvik.system.NativeStart.main(Native Method)

Java

mAdapter = new MyExpandableListAdapter(MainActivity.this, listchapt,
                null);

        elvForDialog.setIndicatorBounds(width - 20, width);// 130
        elvForDialog.setAdapter(mAdapter);

        elvForDialog.setOnGroupClickListener(new OnGroupClickListener() {

            public boolean onGroupClick(ExpandableListView arg0, View arg1,
                    int arg2, long arg3) throws RuntimeException {
                String pos = (String)mAdapter.getGroup(arg2);
                System.out.println("position" + pos);
                List<String> children = new ArrayList<String>();
                children.clear();
                listNames.clear();
                for (int i = 0; i < listchapt.size(); i++) {

                    dbHelper.openDataBase();
                    children = dbHelper.GetSubchapt(pos);
                    dbHelper.close();
                    listNames.add(children);  // line no.143
                }

                System.out.println("position" + pos);
                Display newDisplay = getWindowManager().getDefaultDisplay();
                int width = newDisplay.getWidth();
                mAdapter = new MyExpandableListAdapter(MainActivity.this,
                        listchapt, listNames);
                elvForDialog.setIndicatorBounds(width - 20, width);// 130
                elvForDialog.setAdapter(mAdapter);
                System.out.println("explist" + listSubchapt);

                try {

                    Log.v("LH", "ssetOnGroupClickListener");
                    Log.v("LH", "" + viewListLastSelected.toString());
                    Log.v("LH",
                            "" + ((TextView) viewListLastSelected).getText());

                } catch (Exception e) {
                    Log.v("LH", "ERROR@onCreate: " + e.toString());
                }
                return false;
            }
        });

        elvForDialog.setOnChildClickListener(new OnChildClickListener() {

            public boolean onChildClick(ExpandableListView arg0, View arg1,
                    int arg2, int arg3, long arg4) throws RuntimeException {

                currentChapt = listchapt.get(arg2).toString();
                currentSubchapt = listNames.get(arg2).get(arg3).toString();
                System.out.println("Yes it shows child " + currentChapt
                        + currentSubchapt);
                // createExpandableListViewDialog(1);

                Intent in = new Intent(MainActivity.this, WebContent.class);
                in.putExtra("chapterid", currentChapt);
                in.putExtra("subchaptid", currentSubchapt);
                startActivity(in);

                elvForDialog.clearChildFocus(viewListLastSelected);

                try {

                    viewListLastSelected.setBackgroundDrawable(null);
                    ((TextView) viewListLastSelected).setTextColor(Color.GRAY);
                } catch (Exception e) {
                }
                ((TextView) arg1).setTextColor(Color.WHITE);
                viewListLastSelected = arg1;

                return false;
            }
        });

        elvForDialog.setOnGroupExpandListener(new OnGroupExpandListener() {

            public void onGroupExpand(int groupPosition) {
                int len = mAdapter.getGroupCount();

                for (int i = 0; i < len; i++) {
                    if (i != groupPosition) {
                        elvForDialog.collapseGroup(i);
                    }
                }
            }

        });

MyAdapter类

public class MyExpandableListAdapter extends BaseExpandableListAdapter {
    Activity activity;
    List<String> listGroup = new ArrayList<String>();
    List<List<String>> listChild = new ArrayList<List<String>>();

    private int _posGroup = 0;
    private int _posChild = 0;



    public MyExpandableListAdapter(Activity a, List<String> group, List<List<String>> children){
        super();
        activity = a;
        listGroup = group;
        listChild = children;
    }


    public Object getChild(int groupPosition, int childPosition) {
        return listChild.get(groupPosition).get(childPosition);
    }


    public long getChildId(int groupPosition, int childPosition) {
        //Log.v("LH", "ChildID: " + childPosition);      
        _posGroup = groupPosition;
        _posChild = childPosition;
        return childPosition;
    }


    public int getChildrenCount(int groupPosition) {
        return listChild.get(groupPosition).size();    //line no 51
    }


    public View getChildView(int groupPosition, int childPosition,
            boolean isLastChild, View convertView, ViewGroup parent) {      
        String string = listChild.get(groupPosition).get(childPosition);
        View view = getGenericChildView(string);

        TextView text = (TextView) view;
        if(this._posGroup==groupPosition &&
                   this._posChild==childPosition)         
                {
                    text.setTextColor(Color.rgb(85, 85, 85));
                    text.setTypeface(null, Typeface.BOLD);
                }
       view.setBackgroundResource(R.drawable.menu_submenubg);

        return view;
    }


    //group method stub

    public Object getGroup(int groupPosition) {
        return listGroup.get(groupPosition);
    }

    public int getGroupCount() {
        return listGroup.size();
    }


    public long getGroupId(int groupPosition) {
        //Log.v("LH", "GroupID: " + groupPosition);
        return groupPosition;
    }


    public View getGroupView(int groupPosition, boolean isExpanded,
            View convertView, ViewGroup parent) {      
        String string = listGroup.get(groupPosition);
        View result=getGenericGroupView(string);
        result.setBackgroundResource(R.drawable.menu_hoverbg);
        return result;
    }

    public TextView getGenericChildView(String s) {
        AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
                ViewGroup.LayoutParams.FILL_PARENT, 0);
        lp.height=73; //73,50
        TextView text = new TextView(activity);
        text.setLayoutParams(lp);
        text.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
        text.setPadding(50, 0, 0, 0);
        text.setTextColor(Color.rgb(85, 85, 85));
        text.setTypeface(null, Typeface.BOLD);
        text.setTextSize(15);
        text.setText(s);
        return text;
    }


    public TextView getGenericGroupView(String s) {
        AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
                ViewGroup.LayoutParams.FILL_PARENT, 0);
        lp.height=60;
        TextView text = new TextView(activity);
        text.setLayoutParams(lp);
        text.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
        text.setPadding(20, 0, 0, 0);
        text.setTextSize(20);
        text.setTextColor(Color.WHITE);      
        text.setText(s);
        return text;
    }


    public boolean hasStableIds() {      
        return false;
    }


    public boolean isChildSelectable(int groupPosition, int childPosition) {      
        return true;
    } 

提前感谢..

编辑: DBHelper

public class DBHelper extends SQLiteOpenHelper {
    public int GetCursor;
    private Context myContext;
    public String DB_PATH = "data/data/com.redcaso.mia/databases/"; // path

    public static String DB_NAME = "Test.sqlite";// your database name
    static String ASSETS_DB_FOLDER = "db";
    private SQLiteDatabase db;

    public DBHelper(Context context) {
        super(context, DB_NAME, null, 2);
        if (db != null && db.isOpen())
            close();

        this.myContext = context;
        //DB_NAME = db_name;

        try {
            createDataBase();
            openDataBase();
        } catch (IOException e) {
            // System.out.println("Exception in creation of database : "+
            // e.getMessage());
            e.printStackTrace();
        }

    }



    public void createDataBase() throws IOException {
        boolean dbExist = checkDataBase();

        if (dbExist) {
            // System.out.println("Database Exist");
        } else {
            this.getReadableDatabase();

            try {
                copyDatabase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }
    }

    private void copyDatabase() throws IOException {
        InputStream input = myContext.getAssets().open(DB_NAME);
        String outputFileName = DB_PATH + DB_NAME;
        OutputStream output = new FileOutputStream(outputFileName);

        byte[] buffer = new byte[1024];
        int length;
        while ((length = input.read(buffer)) > 0) {
            output.write(buffer, 0, length);
        }

        // Close the streams
        output.flush();
        output.close();
        input.close();
        // System.out.println(DB_NAME + "Database Copied !");
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public void openDataBase() throws SQLException {
        // Open the database
        String myPath = DB_PATH + DB_NAME;
        db = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READWRITE);
    }

    public boolean isOpen() {
        if (db != null)
            return db.isOpen();
        return false;
    }

    @Override
    public synchronized void close() {
        if (db != null)
            db.close();
        super.close();
    }

    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;
        try {
            String myPath = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READWRITE);

        } catch (Exception e) {
            // database does't exist yet.
        }

        if (checkDB != null) {
            checkDB.close();
        }

        return checkDB != null ? true : false;
    }

    public Cursor execCursorQuery(String sql) {
        Cursor cursor = null;
        try {
            cursor = db.rawQuery(sql, null);
            GetCursor = cursor.getCount();
            Log.i("Inside execCursorQuery try", sql);
        } catch (Exception e) {
            Log.i("Inside execCursorQuery exception", e.getMessage());
        }
        return cursor;
    }

    public void execNonQuery(String sql) {
        try {
            db.execSQL(sql);
            // Log.d("SQL", sql);
        } catch (Exception e) {
            // Log.e("Err", e.getMessage());
        } finally {
            // closeDb();
        }
    }

    public ArrayList<String> GetchapterID(){
        String sql="";
            //System.out.println("Inside Database");
            sql="select distinct(ChapterId) from contents";

        ArrayList<String> list = new ArrayList<String>();
        Cursor cursor=db.rawQuery(sql, null);

        try{
        if(cursor != null){
        if (cursor.moveToFirst()) {
            do {
                list.add(cursor.getString(0));
            }
            while (cursor.moveToNext());
        }
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
        }
        }
     else
            Toast.makeText(myContext, "No values in DB", Toast.LENGTH_SHORT).show();
        }
        catch(Exception e){
            System.out.println("GetGradeNames(): " +e);
        }
        return list;
    }
    public ArrayList<String> GetSubchapt(String type){
        String sql="";
            sql="select distinct(SubchapterId) from contents where ChapterId='"+type+"'";

        ArrayList<String> list = new ArrayList<String>();
        Cursor cursor=db.rawQuery(sql, null);

        try{
        if(cursor != null){
        if (cursor.moveToFirst()) {
            do {
                list.add(cursor.getString(0));
            }
            while (cursor.moveToNext());
        }
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
        }
        }
     else
            Toast.makeText(myContext, "No Property in DB", Toast.LENGTH_SHORT).show();
        }
        catch(Exception e){
            System.out.println("GetLevelNames(): " +e);
        }
        return list;
    }
    public ArrayList<String> GetName(String chapter,String subchapt){
        String sql="";
            sql="select distinct(filename) from contents where SubchapterId='"+subchapt+"' and ChapterId='"+chapter+"'";

        ArrayList<String> list = new ArrayList<String>();
        Cursor cursor=db.rawQuery(sql, null);
        //list.add("All Topics - Entire "+grade);
        try{
        if(cursor != null){
        if (cursor.moveToFirst()) {
            do {
                list.add(cursor.getString(0));
            }
            while (cursor.moveToNext());
        }
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
        }
        }
     else
            Toast.makeText(myContext, "No Address in DB", Toast.LENGTH_SHORT).show();
        }
        catch(Exception e){
            //System.out.println("GetBasicTopicNames(): " +e);
        }
        return list;
    }

2 个答案:

答案 0 :(得分:2)

您将孩子存放错误,并且每次添加新孩子时都不必重新创建适配器。

以下是一些使您的代码正常运行的修复程序:

将适配器构造函数更改为,因此它只接收活动和组:

public MyExpandableListAdapter(Activity a, List<String> group){
    this.activity = a;
    this.listGroup = group;
}

更改子项列表的类型,以便您可以通过groupPosition访问它们,如下所示:

SparseArray<List<String>> listChild = new SparseArray<List<String>>();

现在在适配器中创建一个添加子项的新方法:

public addChildren(int groupPosition, List<String> children) {
    this.listChild.put(groupPosition, children);
}

现在已经处理了适配器,修复了OnGroupClick事件。不是每次都设置新的适配器,而是添加或删除子项(基于子项是否已存在):

expList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
    @Override
    public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
        if (mAdapter.getChildrenCount == 0) {
            dbHelper.openDataBase();
            children = dbHelper.GetSubchapt(pos);
            dbHelper.close();
            mAdapter.addChildren(groupPosition, children);
        }
        else
            mAdapter.removeChildren(groupPosition);
        return false;
    }
});

GroupClick事件现已修复。剩下的就是调整你的getChildrenCount方法,这样它就不会抛出NPE:

public int getChildrenCount(int groupPosition) {
    if (listChild.get(groupPosition) == null) {
        Log.e("mAdapter.getChildrenCount", "Tried to access group's "+
        groupPosition+" children which have not yet been added!");
        return 0;
    }
    else  
        return listChild.get(groupPosition).size();
}

发布可能发生的任何其他错误,因为此代码未通过您的设置进行测试。

答案 1 :(得分:0)

所以你的问题出在你的onGroupClick上。返回值为false表示不处理click事件,因此在日志中找不到任何内容是正常的,因为在SDK中调用了expandGroup。

尝试在onGroupClick中返回true值并自行处理折叠/展开。

 public boolean onGroupClick(ExpandableListView arg0, View arg1,
                int arg2, long arg3) throws RuntimeException {
            String pos = (String)mAdapter.getGroup(arg2);
            System.out.println("position" + pos);
            List<String> children = new ArrayList<String>();
            children.clear();
            listNames.clear();
            for (int i = 0; i < listchapt.size(); i++) {

                dbHelper.openDataBase();
                children = dbHelper.GetSubchapt(pos);
                dbHelper.close();
                listNames.add(children);  // line no.143
            }

            System.out.println("position" + pos);
            Display newDisplay = getWindowManager().getDefaultDisplay();
            int width = newDisplay.getWidth();
            mAdapter = new MyExpandableListAdapter(MainActivity.this,
                    listchapt, listNames);
            elvForDialog.setIndicatorBounds(width - 20, width);// 130
            elvForDialog.setAdapter(mAdapter);
            System.out.println("explist" + listSubchapt);

            try {

                Log.v("LH", "ssetOnGroupClickListener");
                Log.v("LH", "" + viewListLastSelected.toString());
                Log.v("LH",
                        "" + ((TextView) viewListLastSelected).getText());

            } catch (Exception e) {
                Log.v("LH", "ERROR@onCreate: " + e.toString());
            }

            if (elvForDialog.isGroupExpanded(arg2))
                elvForDialog.collapseGroup(arg2);
            else
                elvForDialog.expandGroup(arg2);

            return true;
        }
    });