Android ExpandableListView und SimpleCursorTreeAdapter

f4b1

Mitglied
Hallo zusammen,

ich möchte Daten aus der SQLite-DB via SimpleCursorTreeAdapter in einer ExpandableListView anzeigen.

Der Ergebniscursor nach dem query sieht z.B. so aus:

Code:
_id         nameZimmer   nameVerbraucher      power  image
----------  ----------  -------------  ----------  ----------
1           Küche       Waschmaschine  2.0         2130837528
2           Küche       Kaffeemaschin  0.0         2130837514
3           Küche       Backofen       3264.0      2130837506
4           Küche       Spülmaschine   0.0         2130837510
5           Küche       Trockner       2.0         2130837524
6           Küche       Herd           0.0         2130837512
7           Küche       Kühlschrank    170.0       2130837516
8           Küche       Gefrierschran  200.0       2130837508

Das erste "name" steht dabei für den Namen des Zimmers, das Zweite für einen Stromverbraucher in diesem Zimmer.

Ich möchte nun, dass in der ExpandableListView, als Group, der Name des Zimmers angezeigt wird und als Child-Elemente die einzelnen Verbraucher mit deren Verbrauch (power). Zu dem Verbraucher soll noch ein passendes Icon angezeigt werden, dies entspricht der Spalte "image".

Die Layouts für Group/Child sind natürlich vorhanden.

Hier ein Code-Schnippsel der die relevanten Teile zeigt:

Java:
public class TestActivity extends ExpandableListActivity {
  
  private ExpandableListView mListView;
  private SimpleCursorTreeAdapter mAdapter;
  private DB db;
  private SQLiteDatabase dbConn;
  
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.verbrauch_extended_list);
   
    String sql = "SELECT verbraucher._id AS _id, zimmer.name, verbraucher.name, details.power, verbraucher.image " +
    	"FROM zimmer " +
      "JOIN verbraucher ON zimmer._id = verbraucher.zimmer_id " + 
      "LEFT OUTER JOIN details ON verbraucher.uuid = details.uuid WHERE details.power";
    
    mListView = (ExpandableListView) findViewById(android.R.id.list);
    db = new DB(this);
    dbConn = db.getReadableDatabase();
    
    Cursor ergebnis = dbConn.rawQuery(sql, null);
    
    mAdapter = new SimpleCursorTreeAdapter(
        this, 
        ergebnis, 
        R.layout.group, 
        new String[] { "zimmer.name" }, 
        new int[] { R.id.zimmer_name }, 
        R.layout.hchild, 
        new String[] { "verbraucher.image" , "verbraucher.name"  , "details.power" }, 
        new int[] { R.id.verbraucher_image , R.id.verbraucher_name , R.id.verbraucher_power }) {
      
      @Override
      protected Cursor getChildrenCursor(Cursor groupCursor) {
        // TODO Auto-generated method stub
        return null;
      }
    };
    
    mListView.setAdapter(mAdapter);
    
  }
}


Irgendwarum bekomm ich, sobald ich das ausführe, eine NullPointerException:


Code:
03-01 17:14:36.424: ERROR/AndroidRuntime(899): FATAL EXCEPTION: main
03-01 17:14:36.424: ERROR/AndroidRuntime(899): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.test/TestActivity}: java.lang.NullPointerException
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at android.os.Looper.loop(Looper.java:123)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at android.app.ActivityThread.main(ActivityThread.java:4627)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at java.lang.reflect.Method.invokeNative(Native Method)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at java.lang.reflect.Method.invoke(Method.java:521)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at dalvik.system.NativeStart.main(Native Method)
03-01 17:14:36.424: ERROR/AndroidRuntime(899): Caused by: java.lang.NullPointerException
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at android.widget.SimpleCursorTreeAdapter.initFromColumns(SimpleCursorTreeAdapter.java:194)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at android.widget.SimpleCursorTreeAdapter.initChildrenFromColumns(SimpleCursorTreeAdapter.java:205)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at android.widget.SimpleCursorTreeAdapter.init(SimpleCursorTreeAdapter.java:186)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at android.widget.SimpleCursorTreeAdapter.<init>(SimpleCursorTreeAdapter.java:169)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at de.test.TestActivity$1.<init>(VerbraucherTestActivity.java:41)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at de.smarthome.gui.TestActivity.onCreate(TestActivity.java:49)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
03-01 17:14:36.424: ERROR/AndroidRuntime(899):     ... 11 more

Bin dankbar für jede Hilfe!

Grüße!
 
Zuletzt bearbeitet:

f4b1

Mitglied
Ich bin inzw. ein bisschen weiter gekommen:

Wenn ich den SQL-Query in der Konsole ausführe, bekomme ich das Ergebnis wie im ersten Post.

Ich habe nun mal versucht, den Inhalt des Ergebnis-Cursor via Log.d(String,String) ausgeben zu lassen:

Java:
Log.d(TAG, "ergebnis.getString(2): " + ergebnis.getString(2));

Sobald diese Zeile abgearbeitet wird, fliegt mir eine
Code:
03-02 09:40:06.583: ERROR/AndroidRuntime(635): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.test/TestActivity}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 8

Ich versteh nicht, wieso dort "Index -1" steht? "Size of 8" entspricht wohl der Anzahl an Datensätzen aus dem Query.

Ich bin dann weiter so vorgegangen, dass ich die Log-Ausgabe auskommentiert habe und zusätzlich
Java:
@Override
      protected Cursor getChildrenCursor(Cursor groupCursor) {
        // TODO Auto-generated method stub
        return null;
      }

in

Java:
@Override
      protected Cursor getChildrenCursor(Cursor groupCursor) {
        // TODO Auto-generated method stub
        return groupCursor;
      }

abgeändert habe.

Wenn ich die Activity nun aufrufe, bekomm ich in meiner ExpListView lediglich die Ausgabe: "No Data" (ist gewünscht, wenn keine Daten zur Anzeige vorhanden sind.)


Also nochmal zusammengefasst:
Wenn ich mir den Inhalt aus dem Ergebniscursor anzeigen lassen möchte, fliegt ne CursorIndexOutOfBoundException. Wenn in der Methode "protected Cursor getChildrenCursor(Cursor groupCursor)" als return value "null" zurückgegeben wird, fliegt ne NullPointerException. Ändere ich den Rückgabewert auf groupCursor, wird in meiner ExpListView "No Data" angezeigt.

Evtl. hilft das ein wenig weiter...

Ich hab schon nach Codeschnipsel für mein Problem gesucht, wurde aber nicht fündig :/

Merci!




//// EDIT

Also, ich hab das Problem nun gelöst:

Es ist wichtig, dass man
Java:
@Override
      protected Cursor getChildrenCursor(Cursor groupCursor) { ... }
implementiert!

Ich habe einfach das selbe Query wie schon für die Gruppe genommen und damit einen neuen Cursor erzeugt. Dieser wird von der getChildrenCursor(Cursor groupCursor)-Methode zurückgegeben. Die ExpList wird dann mit Daten gefüllt!

Nun gilts blos noch die SQL-Stmts. so anzupassen dass auch das drin steht was drin stehen soll :)

Weiter geht's! :)
 
Zuletzt bearbeitet:

Neue Themen


Oben