Cómo crear ListView multinivel en Android

necesito crear una lista multi nivel. como esta imagen

Lista de varios niveles

trato esto y esto

pero no tiene idea de cómo implementar la vista de lista de varios niveles.

trato de crear mi propia como esta

main1.xml

<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollbars="none" android:background="#ffffff" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff" android:id="@+id/add" android:orientation="vertical" /> </ScrollView> 

TreenodeDatabase.java

  package com.android.treenode; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteStatement; import android.util.Log; public class TreenodeDatabase { private static final String DB_NAME1 = "treenode.sqlite3"; private static final int databse_version=1; private Context m_contextObj = null ; private SQLiteDatabase db = null ; private SQLiteStatement insertstmt; int totalcolms; public TreenodeDatabase(Context ctx) { m_contextObj = ctx; OpenHelper oh=new OpenHelper (m_contextObj); this.db=oh.getWritableDatabase(); } public void CloseDB() { try { db.close(); } catch(Exception ex) { } finally{ db=null; //return nt; } } public void getContinentData(){ Cursor mCursor = null; String SqlQuery = null; int numRows; SqlQuery = "Select * from Continent"; Log.d("Query ------>",SqlQuery); try{ ArrayListClass.continent.clear(); }catch (Exception e) { // TODO: handle exception } try { mCursor = db.rawQuery(SqlQuery, null); if(mCursor != null) { numRows = mCursor.getCount(); Log.e("1",""); mCursor.moveToFirst(); for (int i = 0; i < numRows; ++i) { ObjectClass obj = new ObjectClass(); obj.continent_id = mCursor.getString(0).toString().replace('$',' ').trim().toString(); obj.continent = mCursor.getString(1).toString().replace('$',' ').trim().toString(); ArrayListClass.continent.add(obj); mCursor.moveToNext(); } } } catch (SQLException e) { } finally{ try{ mCursor.close(); mCursor=null; }catch (Exception e) { // TODO: handle exception } } } public void getCountryData(String continent_id){ Cursor mCursor = null; String SqlQuery = null; int numRows; SqlQuery = "Select * from Country where Rid=" + continent_id; Log.d("Query ------>",SqlQuery); try{ ArrayListClass.country.clear(); }catch (Exception e) { // TODO: handle exception } try { mCursor = db.rawQuery(SqlQuery, null); if(mCursor != null) { numRows = mCursor.getCount(); Log.e("1",""); mCursor.moveToFirst(); for (int i = 0; i < numRows; ++i) { ObjectClass obj = new ObjectClass(); obj.country_id = mCursor.getString(0).toString().replace('$',' ').trim().toString(); obj.country = mCursor.getString(1).toString().replace('$',' ').trim().toString(); obj.country_ref_id = mCursor.getString(2).toString().replace('$',' ').trim().toString(); ArrayListClass.country.add(obj); mCursor.moveToNext(); } } } catch (SQLException e) { } finally{ try{ }catch (Exception e) { // TODO: handle exception } try{ mCursor.close(); mCursor=null; }catch (Exception e) { // TODO: handle exception } } } public void getStateData(String country_id){ Cursor mCursor = null; String SqlQuery = null; int numRows; SqlQuery = "Select * from State where Rid=" + country_id; Log.d("Query ------>",SqlQuery); try{ ArrayListClass.state.clear(); }catch (Exception e) { // TODO: handle exception } try { mCursor = db.rawQuery(SqlQuery, null); if(mCursor != null) { numRows = mCursor.getCount(); Log.e("1",""); mCursor.moveToFirst(); for (int i = 0; i < numRows; ++i) { ObjectClass obj = new ObjectClass(); obj.state_id = mCursor.getString(0).toString().replace('$',' ').trim().toString(); obj.state = mCursor.getString(1).toString().replace('$',' ').trim().toString(); obj.state_ref_id = mCursor.getString(2).toString().replace('$',' ').trim().toString(); ArrayListClass.state.add(obj); mCursor.moveToNext(); } } } catch (SQLException e) { } finally{ try{ mCursor.close(); mCursor=null; }catch (Exception e) { // TODO: handle exception } } } public void getRegionData(String state_id){ Cursor mCursor = null; String SqlQuery = null; int numRows; SqlQuery = "Select * from Region where Rid=" + state_id; Log.d("Query ------>",SqlQuery); try{ ArrayListClass.region.clear(); }catch (Exception e) { // TODO: handle exception } try { mCursor = db.rawQuery(SqlQuery, null); if(mCursor != null) { numRows = mCursor.getCount(); Log.e("1",""); mCursor.moveToFirst(); for (int i = 0; i < numRows; ++i) { ObjectClass obj = new ObjectClass(); obj.region_id = mCursor.getString(0).toString().replace('$',' ').trim().toString(); obj.region = mCursor.getString(1).toString().replace('$',' ').trim().toString(); obj.region_ref_id = mCursor.getString(2).toString().replace('$',' ').trim().toString(); ArrayListClass.region.add(obj); mCursor.moveToNext(); } } } catch (SQLException e) { } finally{ try{ mCursor.close(); mCursor=null; }catch (Exception e) { // TODO: handle exception } } } public void getAreaData(String region_id){ Cursor mCursor = null; String SqlQuery = null; int numRows; SqlQuery = "Select * from Area where Rid=" + region_id; Log.d("Query ------>",SqlQuery); try{ ArrayListClass.area.clear(); }catch (Exception e) { // TODO: handle exception } try { mCursor = db.rawQuery(SqlQuery, null); if(mCursor != null) { numRows = mCursor.getCount(); Log.e("1",""); mCursor.moveToFirst(); for (int i = 0; i < numRows; ++i) { ObjectClass obj = new ObjectClass(); obj.area_id = mCursor.getString(0).toString().replace('$',' ').trim().toString(); obj.area = mCursor.getString(1).toString().replace('$',' ').trim().toString(); obj.area_ref_id = mCursor.getString(2).toString().replace('$',' ').trim().toString(); ArrayListClass.area.add(obj); mCursor.moveToNext(); } } } catch (SQLException e) { } finally{ try{ mCursor.close(); mCursor=null; }catch (Exception e) { // TODO: handle exception } } } public long insert(String values){ Log.e("DbHelper : ", "Insert function called " + values); this.insertstmt=this.db.compileStatement(values); Log.e("DbHelper :", "Executing insert query here "); return this.insertstmt.executeInsert(); } private static class OpenHelper extends SQLiteOpenHelper { OpenHelper(Context context){ super(context, DB_NAME1, null, databse_version); } @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub db.execSQL("CREATE TABLE "+"Continent"+"(Id INTEGER PRIMARY KEY AUTOINCREMENT,Name TXT)"); db.execSQL("CREATE TABLE "+"Country"+"(Id INTEGER PRIMARY KEY AUTOINCREMENT,Name TXT,Rid TXT)"); db.execSQL("CREATE TABLE "+"State"+"(Id INTEGER PRIMARY KEY AUTOINCREMENT,Name TXT,Rid TXT)"); db.execSQL("CREATE TABLE "+"Region"+"(Id INTEGER PRIMARY KEY AUTOINCREMENT,Name TXT,Rid TXT)"); db.execSQL("CREATE TABLE "+"Area"+"(Id INTEGER PRIMARY KEY AUTOINCREMENT,Name TXT,Rid TXT)"); } @Override public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) { // TODO Auto-generated method stub } } } 

ObjectClass.java

 package com.android.treenode; public class ObjectClass{ String continent = ""; String country = ""; String state = ""; String region = ""; String area = ""; String continent_id = ""; String country_id = ""; String state_id = ""; String region_id = ""; String area_id = ""; String country_ref_id = ""; String state_ref_id = ""; String region_ref_id = ""; String area_ref_id = ""; public static boolean [] showcountry = null; public static boolean [] showstate = null; public static boolean [] showregion = null; public static boolean [] showarea = null; //public static Bitmap b; } 

ArrayListClass.java

 package com.android.treenode; import java.util.ArrayList; public class ArrayListClass{ public static ArrayList<ObjectClass> continent = new ArrayList<ObjectClass>(); public static ArrayList<ObjectClass> country = new ArrayList<ObjectClass>(); public static ArrayList<ObjectClass> state = new ArrayList<ObjectClass>(); public static ArrayList<ObjectClass> region = new ArrayList<ObjectClass>(); public static ArrayList<ObjectClass> area = new ArrayList<ObjectClass>(); //public static ArrayList<ObjectClass,ArrayList<ObjectCl> area1 = new ArrayList<ObjectClass,area>(); } 

TreenodeActivity.java

 package com.android.treenode; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.TextView; import android.widget.Toast; public class TreenodeActivity extends Activity { TreenodeDatabase tnd; LinearLayout llAdd; int count = 0; float size = 24f; int items = 3; int padding = 50; boolean showcountry; boolean showstate = true,showregion = true,showarea = true; //*//** Called when the activity is first created. *//* @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main1); insertMethod(); try{ tnd = new TreenodeDatabase(this); tnd.getContinentData(); tnd.CloseDB(); }catch (Exception e) { // TODO: handle exception } llAdd = (LinearLayout)findViewById(R.id.add); //showcountry = new boolean[ArrayListClass.continent.size()]; for(int i=0; i<ArrayListClass.continent.size(); i++){ final int a = i; final LinearLayout ll = new LinearLayout(this); ll.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); ll.setGravity(Gravity.LEFT|Gravity.CENTER); ll.setBackgroundColor(Color.WHITE); ll.setOrientation(LinearLayout.VERTICAL); final TextView tv = new TextView(this); tv.setText(ArrayListClass.continent.get(i).continent + ""); tv.setTextSize(size); tv.setTextColor(Color.BLACK); tv.setGravity(Gravity.LEFT|Gravity.CENTER); tv.setBackgroundColor(Color.WHITE); tv.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub try{ tnd = new TreenodeDatabase(getBaseContext()); tnd.getCountryData(ArrayListClass.continent.get(a).continent_id); tnd.CloseDB(); }catch (Exception e) { // TODO: handle exception } if(showcountry){ if(ArrayListClass.country.size()>0){ for(int i = 0; i<ArrayListClass.country.size(); i++){ final int b = i; final LinearLayout ll1 = new LinearLayout(getBaseContext()); if(i==0){ try{ ll1.removeAllViews(); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } ll1.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); ll1.setGravity(Gravity.LEFT|Gravity.CENTER); ll1.setBackgroundColor(Color.WHITE); ll1.setOrientation(LinearLayout.VERTICAL); ll1.setPadding(50, 1, 1, 1); final TextView tv1 = new TextView(getBaseContext()); tv1.setText(ArrayListClass.country.get(i).country + ""); tv1.setTextSize(size); tv1.setTextColor(Color.BLACK); tv1.setGravity(Gravity.LEFT|Gravity.CENTER); tv1.setBackgroundColor(Color.WHITE); tv1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub try{ tnd = new TreenodeDatabase(getBaseContext()); tnd.getStateData(ArrayListClass.country.get(b).country_id); tnd.CloseDB(); }catch (Exception e) { // TODO: handle exception } if(showstate){ if(ArrayListClass.state.size()>0){ for(int i = 0; i<ArrayListClass.state.size(); i++){ final LinearLayout ll2 = new LinearLayout(getBaseContext()); ll2.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); ll2.setGravity(Gravity.LEFT|Gravity.CENTER); ll2.setBackgroundColor(Color.WHITE); ll2.setOrientation(LinearLayout.VERTICAL); ll2.setPadding(50, 1, 1, 1); final TextView tv2 = new TextView(getBaseContext()); tv2.setText(ArrayListClass.state.get(i).state + ""); tv2.setTextSize(size); tv2.setTextColor(Color.BLACK); tv2.setGravity(Gravity.LEFT|Gravity.CENTER); tv2.setBackgroundColor(Color.WHITE); tv2.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub try{ tnd = new TreenodeDatabase(getBaseContext()); tnd.getRegionData(ArrayListClass.state.get(b).state_id); tnd.CloseDB(); }catch (Exception e) { // TODO: handle exception } if(showregion){ if(ArrayListClass.region.size()>0){ for(int i = 0; i<ArrayListClass.region.size(); i++){ final LinearLayout ll3 = new LinearLayout(getBaseContext()); ll3.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); ll3.setGravity(Gravity.LEFT|Gravity.CENTER); ll3.setBackgroundColor(Color.WHITE); ll3.setOrientation(LinearLayout.VERTICAL); ll3.setPadding(50, 1, 1, 1); final TextView tv3 = new TextView(getBaseContext()); tv3.setText(ArrayListClass.region.get(i).region + ""); tv3.setTextSize(size); tv3.setTextColor(Color.BLACK); tv3.setGravity(Gravity.LEFT|Gravity.CENTER); tv3.setBackgroundColor(Color.WHITE); tv3.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub try{ tnd = new TreenodeDatabase(getBaseContext()); tnd.getAreaData(ArrayListClass.region.get(b).region_id); tnd.CloseDB(); }catch (Exception e) { // TODO: handle exception } if(showarea){ if(ArrayListClass.area.size()>0){ for(int i = 0; i<ArrayListClass.area.size(); i++){ LinearLayout ll4 = new LinearLayout(getBaseContext()); ll4.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); ll4.setGravity(Gravity.LEFT|Gravity.CENTER); ll4.setBackgroundColor(Color.WHITE); ll4.setOrientation(LinearLayout.VERTICAL); ll4.setPadding(50, 1, 1, 1); final TextView tv4 = new TextView(getBaseContext()); tv4.setText(ArrayListClass.area.get(i).area+ ""); tv4.setTextSize(size); tv4.setTextColor(Color.BLACK); tv4.setGravity(Gravity.LEFT|Gravity.CENTER); tv4.setBackgroundColor(Color.WHITE); tv4.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Log.e("Log","clicked" + tv4.getText().toString()); Toast.makeText(getBaseContext(), tv4.getText().toString(), Toast.LENGTH_SHORT).show(); } }); ll4.addView(tv4); ll3.addView(ll4); } } showarea = false; }else{ ArrayListClass.area.clear(); ll3.removeAllViews(); ll3.addView(tv3); showarea = true; } //tv3.setClickable(false); } }); ll3.addView(tv3); ll2.addView(ll3); //tv3.setClickable(false); } } showregion = false; }else{ ArrayListClass.region.clear(); ArrayListClass.area.clear(); ll2.removeAllViews(); ll2.addView(tv2); showregion = true; } //tv2.setClickable(false); } }); ll2.addView(tv2); ll1.addView(ll2); //tv2.setClickable(false); } } showstate = false; }else{ ArrayListClass.state.clear(); ArrayListClass.region.clear(); ArrayListClass.area.clear(); ll1.removeAllViews(); ll1.addView(tv1); showstate = true; } //tv1.setClickable(false); } }); ll1.addView(tv1); ll.addView(ll1); //tv1.setClickable(false); } } showcountry = false; }else{ ArrayListClass.state.clear(); ArrayListClass.region.clear(); ArrayListClass.area.clear(); ArrayListClass.country.clear(); ll.removeAllViews(); ll.addView(tv); showcountry = true; } //tv.setClickable(false); } }); ll.addView(tv); llAdd.addView(ll); } Log.e("Log","Check"); } public void insertMethod(){ tnd = new TreenodeDatabase(this); StringBuilder st = new StringBuilder(); st.append("insert into Continent(Name) values('" + "Continent1" + "');") ; tnd.insert(st.toString()); tnd.CloseDB(); tnd = new TreenodeDatabase(this); StringBuilder st1 = new StringBuilder(); st1.append("insert into Continent(Name) values('" + "Continent2" + "');") ; tnd.insert(st1.toString()); tnd.CloseDB(); tnd = new TreenodeDatabase(this); StringBuilder st2 = new StringBuilder(); st2.append("insert into Country(Name,Rid) values('" + "Country1A" + "','" + "1" + "');") ; tnd.insert(st2.toString()); tnd.CloseDB(); tnd = new TreenodeDatabase(this); StringBuilder st3 = new StringBuilder(); st3.append("insert into Country(Name,Rid) values('" + "Country1B" + "','" + "1" + "');") ; tnd.insert(st3.toString()); tnd.CloseDB(); tnd = new TreenodeDatabase(this); StringBuilder st4 = new StringBuilder(); st4.append("insert into Country(Name,Rid) values('" + "Country2A" + "','" + "2" + "');") ; tnd.insert(st4.toString()); tnd.CloseDB(); tnd = new TreenodeDatabase(this); StringBuilder st5 = new StringBuilder(); st5.append("insert into Country(Name,Rid) values('" + "Country2B" + "','" + "2" + "');") ; tnd.insert(st5.toString()); tnd.CloseDB(); tnd = new TreenodeDatabase(this); StringBuilder st6 = new StringBuilder(); st6.append("insert into State(Name,Rid) values('" + "State1" + "','" + "1" + "');") ; tnd.insert(st6.toString()); tnd.CloseDB(); tnd = new TreenodeDatabase(this); StringBuilder st7 = new StringBuilder(); st7.append("insert into State(Name,Rid) values('" + "State2" + "','" + "1" + "');") ; tnd.insert(st7.toString()); tnd.CloseDB(); tnd = new TreenodeDatabase(this); StringBuilder st8 = new StringBuilder(); st8.append("insert into Region(Name,Rid) values('" + "Region1" + "','" + "1" + "');") ; tnd.insert(st8.toString()); tnd.CloseDB(); tnd = new TreenodeDatabase(this); StringBuilder st9 = new StringBuilder(); st9.append("insert into Area(Name,Rid) values('" + "Area1" + "','" + "1" + "');") ; tnd.insert(st9.toString()); tnd.CloseDB(); } } 

por favor me ayude creo que estoy cerca de éxito .. esto no está funcionando bien. lo que me perdí en esto.

EDITAR

salida de loccat

09-20 16: 27: 52.254: E / Database (5598): close () nunca fue llamado explícitamente en la base de datos '/data/data/com.android.treenode/databases/treenode.sqlite3' 09-20 16:27: 52.254: E / Database (5598): android.database.sqlite.DatabaseObjectNotClosedException: La aplicación no cerró el cursor o el objeto de base de datos que se abrió aquí 09-20 16: 27: 52.254: E / Database (5598): en android.database .sqlite.SQLiteDatabase (SQLiteDatabase.java:1960) 09-20 16: 27: 52.254: E / Database (5598): en android.database.sqlite.SQLiteDatabase.openDatabase (SQLiteDatabase.java:906) 09-20 16: 27: 52.254: E / Database (5598): en android.database.sqlite.SQLiteDatabase.openOrCreateDatabase (SQLiteDatabase.java:940) 09-20 16: 27: 52.254: E / Database (5598): en android.database.sqlite .SQLiteDatabase.openOrCreateDatabase (SQLiteDatabase.java:933) 09-20 16: 27: 52.254: E / Database (5598): en android.app.ContextImpl.openOrCreateDatabase (ContextImpl.java:614) 09-20 16: 27: 52.254 : E / Database (5598): en android.database.sqlite.SQLiteOpenHelper.getWritableDa tabase (SQLiteOpenHelper.java:118) 09-20 16: 27: 52.254: E / Database (5598): en com.android.treenode.TreenodeDatabase. (TreenodeDatabase.java:23) 09-20 16: 27: 52.254: E / Base de datos (5598): en com.android.treenode.TreenodeActivity $ 1 $ 1 $ 1.onClick (TreenodeActivity.java:810) 09-20 16: 27: 52.254: E / Database (5598): en android.view.View.performClick (View.java:2533) 09-20 16: 27: 52.254: E / Database (5598): en android.view.View $ PerformClick.run (View.java:9320) 09-20 16: 27: 52.254: E / Base de datos (5598): en android.os.Handler.handleCallback (Handler.java:587) 09-20 16: 27: 52.254: E / Database (5598): en android.os.Handler.dispatchMessage (Handler.java: 92) 09-20 16: 27: 52.254: E / Database (5598): en android.os.Looper.loop (Looper.java:150) 09-20 16: 27: 52.254: E / Database (5598): at android.app.ActivityThread.main (ActivityThread.java:4385) 09-20 16: 27: 52.254: E / Database (5598): en java.lang.reflect.Method.invokeNative (Método nativo) 09-20 16:27 : 52.254: E / Database (5598): en java.lang.reflect.Method.invoke (Method.java:507) 09-20 16: 2 7: 52.254: E / Database (5598): en com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:849) 09-20 16: 27: 52.254: E / Database (5598): at com .android.internal.os.ZygoteInit.main (ZygoteInit.java:607) 09-20 16: 27: 52.254: E / Database (5598): en dalvik.system.NativeStart.main (Método nativo)

creo que es debido a la base de datos no cerrado correctamente. (i manejar esto)

pero el código no está funcionando correctamente algún tiempo que muestra los niveles de los niños de algún tiempo su no. y alguna vez muestra valores dobles.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.