Reputation: 678
I found a lot of question about this problem, but I can't fix it. I have spend a whole day i couldn't solve. I rechecked my for
loop also
If i have parent value 7 if i click on 4th parent its expands and again i click on 2nd parent its expends and working fine. but if i click 5th or 6th or 7th parent i am getting this error.. i don't know where i am wrong in my code..
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 class
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;
}
Thank in advance..
Edit : 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;
}
Upvotes: 0
Views: 2173
Reputation: 1
So your problem is in your onGroupClick. Here the return value is false means the click event is not handled, so it's normal that you found nothing in your log, cuz the expandGroup has been called in the SDK.
Try to return a true value in onGroupClick and handle collapse / expand yourself.
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;
}
});
Upvotes: 0
Reputation: 44118
You are storing your children wrong and you don't have to re-create your adapter every time you add new children.
Here are some fixes to get your code functional:
Change your adapters constructor to, so it receives only activity and groups:
public MyExpandableListAdapter(Activity a, List<String> group){
this.activity = a;
this.listGroup = group;
}
Change the type of your children list, so you can access them by groupPosition, like this:
SparseArray<List<String>> listChild = new SparseArray<List<String>>();
Now create a new method inside the adapter which adds children:
public addChildren(int groupPosition, List<String> children) {
this.listChild.put(groupPosition, children);
}
Now that the adapter is taken care of, fix your OnGroupClick event. Instead of setting a new adapter each time, add or remove the children (based on whether the children already exist):
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 event has been fixed now. What's left is to adjust your getChildrenCount method so it wouldn't throw a 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();
}
Post any further errors that might occur, as this code is not tested with your setup.
Upvotes: 2