ListView-Items einer HashMap<String, String> übergeben

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • ListView-Items einer HashMap<String, String> übergeben

    Hallo zusammen,

    ich bin neu hier im Forum und hätte auch gleich mal eine Frage zu einem Problem.

    Ich versuche zur Zeit einen MP3-Player für Android umzusetzen. Funktioniert soweit alles ganz gut.
    Doch momentan ist es so, dass der Benutzer nur eine Songliste hat und von dieser Liste einen Song zum Abspielen auswählen kann. Natürlich wird dann immer automatisch der nächste Song abgespielt.

    Nun möchte ich aber folgendes umsetzen:
    Es soll eine Songliste geben, von der man einen, mehrere oder alle Songs auswählen kann (per CheckBox) und diese dann einer Playliste hinzufügt.

    Ich habe eine Klasse namens MP3Finder geschrieben, die alle Songs, die sich auf der SD-Karte befinden, ermittelt und in einer ArrayList mit einer HashMap<String, String> speichert. In der MP3Finder-Klasse habe ich eine Methode defniert >>getMP3List()<<, die diese ArrayList<HashMap<String, String>> zurückgibt.

    In meiner SongListActivity habe ich ein ListView das die ganzen Songs aus diesem ListArray<HashMap<>> mittels CheckedTextView-Items auflistet.
    Nun will ich wie bereits weiter oben erwähnt, dass alle ausgewählten Songs (gesetztes Häkchen) in einer neuen ArrayList<HashMap... gespeichert werden, die ich dann mittels einem Intent der PlayListActivity übergeben möchte.

    Doch leider habe ich absolut keine Ahnung, wie ich die ListView-Items der HashMap übergeben soll. Das übergeben bzw. speichern der HashMap-Daten in die ListView habe ich ja mittels einem Adapter umgesetzt. Aber wie macht man das umgekehrt?

    Google spuckt nur Beispiele aus, wie man Daten aus einer HashMap in einer ListView speichert. Umgekehrt habe ich leider keine Beispiele finden können. Daher hoffe ich, dass Ihr mir dabei helfen könnt. :)

    Java-Quellcode

    1. public class SongListActivity extends AppCompatActivity {
    2. // List of mp3 files
    3. ArrayList<HashMap<String, String>> MP3List = new ArrayList<>();
    4. @Override
    5. protected void onCreate(Bundle savedInstanceState) {
    6. super.onCreate(savedInstanceState);
    7. setContentView(R.layout.activity_main);
    8. Button isChecked = (Button) findViewById(R.id.btn_is_checked);
    9. final ListView listView = (ListView) findViewById(R.id.list_view);
    10. MP3Finder mp3Finder = new MP3Finder();
    11. // Get all mp3's from sdcard
    12. this.MP3List = mp3Finder.getMP3List();
    13. // Add items to ListView
    14. ListAdapter adapter = new SimpleAdapter(this, MP3List, R.layout.activity_item, new String[] { "mp3Title" }, new int[] {
    15. R.id.mp3_title});
    16. listView.setAdapter(adapter);
    17. listView.setOnItemClickListener(new CheckBoxClick());
    18. listView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
    19. isChecked.setOnClickListener(new View.OnClickListener() {
    20. @Override
    21. public void onClick(View v) {
    22. SparseBooleanArray checked = listView.getCheckedItemPositions();
    23. int len = listView.getCount();
    24. for (int i = 0; i < len; i++) {
    25. if (checked.get(i)) {
    26. // ...an dieser Stelle möchte ich die ausgewählten Songs aus der ListView
    27. // in meiner ArrayList<HashMap<...>> speichern...
    28. }
    29. }
    30. }
    31. });
    32. }
    33. public class CheckBoxClick implements AdapterView.OnItemClickListener {
    34. @Override
    35. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    36. CheckedTextView checkedTextView = (CheckedTextView) view;
    37. if (checkedTextView.isChecked()) {
    38. Toast.makeText(MainActivity.this, "checked", Toast.LENGTH_SHORT).show();
    39. } else {
    40. Toast.makeText(MainActivity.this, "unchecked", Toast.LENGTH_SHORT).show();
    41. }
    42. }
    43. }
    44. }
    Alles anzeigen

    Ich hoffe ihr habt in etwa verstanden, was ich gerne umsetzen möchte. Ich hoffe ihr könnt mir dabei helfen. Ich würde mich jedenfalls sehr freuen.

    Grüße DaveX78
  • Du bekommst ja die Position in der Liste und die ID. Damit solltest du auf deine Liste zugreifen können und die dann separat speichern.
    MfG,
    Christopher

    Eine gewisses Maß an Freundlichkeit kann man auch von Menschen im Internet erwarten.
    Das Forum basiert komplett auf der Freiwilligkeit ihrer Nutzer und diese sollen sich wohlfühlen! Daher seid bitte freundlich. Danke
  • Hallo Christopher,

    erstmals danke für die Antwort. Die Position oder die ID ist nicht das Problem. Sondern eher das Vorgehen. Ich weiß nicht wie man mein Vorhaben für gewöhnlich umsetzt.
    Zum testen habe ich mal folgendes gemacht:

    Java-Quellcode

    1. isChecked.setOnClickListener(new View.OnClickListener() {
    2. @Override
    3. public void onClick(View v) {
    4. SparseBooleanArray checked = listView.getCheckedItemPositions();
    5. HashMap<String, String> songs = new HashMap<>();
    6. int len = listView.getCount();
    7. for (int i = 0; i < len; i++) {
    8. if (checked.get(i)) {
    9. String item = listView.getAdapter().getItem(checked.keyAt(i)).toString();
    10. System.out.println(item);
    11. }
    12. }
    13. }
    14. });
    Alles anzeigen

    Die Ausgabe ist folgende (wenn beispielsweise ein Item ausgewählt ist):

    Quellcode

    1. {mp3Path=/storage/emulated/0/artist - song.mp3, mp3Title=artist - song}
    Also müsste ich diesen String splitten und dann in einer Hashmap<String, String> den Teil mp3Path=/.. (was auch den Schlüssel darstellt) im ersten <String, ...> und den Teil mp3Title=... im zweiten <..., String> speichern, richtig?

    Gibt es auch eine elegantere Vorgehensweise?

    Edit:
    Mit eleganter meine ich z.B. die Tatsache, dass man den Inhalt einer ArrayList<HashMap<String, String>> mittels einem Adapter in eine ListView übertragen kann. Aber umgekehrt wäre zumindest mir nicht bekannt, dass es auch so elegant geht. Deshalb meine beiden Fragen.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von DaveX78 ()

  • Das beste ist folgendes:
    Baue eine Klasse zusammen, die dann alle Daten hält. Dann hast du eine Liste von Objekten und kannst dann anschließend über die ID einfach nur das Objekt übernehmen. Dafür brauchst du dann aber auch einen neuen Adapter, der deine Klasse verarbeitet. Dort kann man dann auch Sachen, wie ein eigenes Layout einbauen.
    Das ging evtl. nicht so aus dem vorherigen Post hervor. Entschuldige bitte :)

    Ansonsten da du ja Multichoice nimmst, kannst du auch den OnClickListener weglassen und evtl. in der toolbar einen Menüpunkt (normalerweise ein Haken) anlegen und dann alle auslesen. Dann ist das evtl noch ein bisschen effizienter ;)
    MfG,
    Christopher

    Eine gewisses Maß an Freundlichkeit kann man auch von Menschen im Internet erwarten.
    Das Forum basiert komplett auf der Freiwilligkeit ihrer Nutzer und diese sollen sich wohlfühlen! Daher seid bitte freundlich. Danke
  • Der OnClickListener für den Button namens "isChecked" hatte ich sowieso nur zum testen eingebaut. :)
    Ansonsten werde ich mir deinen Vorschlag, eine Klasse die alle Daten enthält, auf jeden Fall durch den Kopf gehen lassen.
    Ich hatte mir für mein konkretes Beispiel folgendes ausgedacht:

    Java-Quellcode

    1. ArrayList<HashMap<String, String>> songToPlayList = new ArrayList<>();
    2. isChecked.setOnClickListener(new View.OnClickListener() {
    3. @Override
    4. public void onClick(View v) {
    5. SparseBooleanArray checked = listView.getCheckedItemPositions();
    6. HashMap<String,String> songs = new HashMap();
    7. int len = listView.getCount();
    8. for (int i = 0; i < len; i++) {
    9. if (checked.get(i)) {
    10. String item = listView.getAdapter().getItem(checked.keyAt(i)).toString();
    11. item = item.substring(1, item.length() - 1); // entfernt { und }
    12. String items[] = item.split(","); // teilt Pfad(Schlüssel) und Titel in zwei Array-Elemente auf
    13. String path = items[0]; // Pfad (gleichzeitig Schlüssel)
    14. String title = items[1]; // Titel
    15. songs.put(path, title);
    16. }
    17. }
    18. songToPlayList.add(songs);
    19. }
    20. });
    Alles anzeigen
    Ist meiner Meinung nach nicht so schön, sollte aber funktionieren. Leider ist mir aber nun ein anderes Problem aufgefallen. :(
    Habe ich jetzt eben erst bemerkt. Entweder verzettelt sich irgendwie die get()-Methode des SparseBooleanArray-Objekts "checked", oder irgendwas geht schief bei den listView-Methoden getAdapter().getItem(...).
    Denn lasse ich mir testweise bei jedem Durchlauf der Schleife den String item mittels System.out.println() ausgeben, werden die falschen Songs angezeigt. Nur die die eben nicht ausgwählt sind, werden richtig angezeigt, nämlich mit "unchecked" - oder wenn alle ausgewählt sind, dann werden auch alle richtig ausgegeben. Finde ich irgendwie seltsam und komme auch nicht drauf wieso das so ist. Denn eigentlich passt ja alles.
  • Grundsätzlich ist das ja eine Lösung, nur halt keine Schöne :D
    Was meinst du denn mit falschen Ausgaben?
    MfG,
    Christopher

    Eine gewisses Maß an Freundlichkeit kann man auch von Menschen im Internet erwarten.
    Das Forum basiert komplett auf der Freiwilligkeit ihrer Nutzer und diese sollen sich wohlfühlen! Daher seid bitte freundlich. Danke
  • Hier mal der Quellcode:

    Java-Quellcode

    1. isChecked.setOnClickListener(new View.OnClickListener() {
    2. @Override
    3. public void onClick(View v) {
    4. SparseBooleanArray checked = listView.getCheckedItemPositions();
    5. int len = listView.getCount();
    6. for (int i = 0; i < len; i++) {
    7. if (checked.get(i)) {
    8. String item = listView.getAdapter().getItem(checked.keyAt(i)).toString();
    9. System.out.println(item);
    10. }
    11. else {
    12. System.out.println("Unchecked");
    13. }
    14. }
    15. }
    16. });
    Alles anzeigen



    Momentan habe ich zum testen 8 Titel als .mp3 auf der SDKarte. Um hier keine Werbung zu machen, die Titel sind folgendermaßen gespeichert:

    Quellcode

    1. {mp3Path=/storage/emulated/0/artist - song1.mp3, mp3Title=artist - song1}
    2. {mp3Path=/storage/emulated/0/artist - song2.mp3, mp3Title=artist - song2}
    3. {mp3Path=/storage/emulated/0/artist - song3.mp3, mp3Title=artist - song3}
    4. {mp3Path=/storage/emulated/0/artist - song4.mp3, mp3Title=artist - song4}
    5. {mp3Path=/storage/emulated/0/artist - song5.mp3, mp3Title=artist - song5}
    6. {mp3Path=/storage/emulated/0/artist - song6.mp3, mp3Title=artist - song6}
    7. {mp3Path=/storage/emulated/0/artist - song7.mp3, mp3Title=artist - song7}
    8. {mp3Path=/storage/emulated/0/artist - song8.mp3, mp3Title=artist - song8}
    Habe ich beispielsweise Song1, Song3, Song7 und Song8 ausgewählt, gibt mir println() folgendes aus:


    Quellcode

    1. System.out: {mp3Path=/storage/emulated/0/artist - song1.mp3, mp3Title=artist - song1} <-richtig
    2. System.out: Unchecked <- richtig
    3. System.out: {mp3Path=/storage/emulated/0/artist - song7.mp3, mp3Title=artist - song7} <-falsch
    4. System.out: Unchecked <- richtig
    5. System.out: Unchecked <- richtig
    6. System.out: Unchecked <- richtig
    7. System.out: {mp3Path=/storage/emulated/0/artist - song1.mp3, mp3Title=artist - song1} <-falsch
    8. System.out: {mp3Path=/storage/emulated/0/artist - song1.mp3, mp3Title=artist - song1} <-falsch
    UPDATE:
    Okay - ich konnte das Problem beheben. :)

    Ich habe diese Code-Zeile:

    Java-Quellcode

    1. String item = listView.getAdapter().getItem(checked.keyAt(i)).toString();
    durch die folgende ersetzt:

    Java-Quellcode

    1. String item = listView.getItemAtPosition(i).toString();
    Nun werden die ausgewählten Songs 100% richtig angezeigt. ;)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von DaveX78 ()