Ich bin neu in der Android-Programmierung und habe Probleme beim Übergeben einer ArrayList eines Pakets an ein Fragment. Dies ist die Aktivität , die gestartet wird (gut funktioniert!) , Wo Feed ist ein Arraylist einer Parcel Musik .
Intent in = new Intent(context, ListMusicsActivity.class);
in.putExtra("arrayMusic", feedList);
activity.startActivity(in);
Die Fragment Activity onCreate () -Methode:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activitymusiclist);
if(savedInstanceState != null)
{
ListMusicFragment frag = new ListMusicFragment();
frag.setArguments(getIntent().getExtras());
}
}
Der Fragmentcode:
public class ListMusicFragment extends SherlockFragment{
private ArrayList<Music> listMusics = new ArrayList<Music>();
private ListView listMusic;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
listMusics = (ArrayList<Music>) getArguments().getSerializable("arrayMusic");
View view = inflater.inflate(R.layout.musiclistview, container, false);
listMusic = (ListView) view.findViewById(R.id.musicListView);
listMusic.setAdapter(new MusicBaseAdapter(getActivity(), listMusics));
return view;
}
}
Ich denke, das Problem liegt in der Leitung
listMusics = (ArrayList<Music>) getArguments().getSerializable("arrayMusic");
Endlich ist das meine Musikklasse:
public class Music implements Parcelable{
private String url;
private String artist;
private String title;
private String duration;
private String info_url;
private String lyrics;
public Music(String url, String artist, String title,
String duration, String lyrics, String info_url)
{
this.url = url;
this.artist = artist;
this.title = title;
this.duration = duration;
this.lyrics = lyrics;
this.info_url = info_url;
}
public Music(Parcel in)
{
url = ParcelUtils.readString(in);
artist = ParcelUtils.readString(in);
title = ParcelUtils.readString(in);
duration = ParcelUtils.readString(in);
info_url = ParcelUtils.readString(in);
lyrics = ParcelUtils.readString(in);
}
public String getUrl()
{
return url;
}
public String getArtist()
{
return artist;
}
public String getTitle()
{
return title;
}
public String getDuration()
{
return duration;
}
public String getLyrics()
{
return lyrics;
}
public String getInfo()
{
return info_url;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
ParcelUtils.writeString(dest, url);
ParcelUtils.writeString(dest, artist);
ParcelUtils.writeString(dest, title);
ParcelUtils.writeString(dest, duration);
ParcelUtils.writeString(dest, lyrics);
ParcelUtils.writeString(dest, info_url);
}
public static final Parcelable.Creator<Music> CREATOR =
new Parcelable.Creator<Music>() {
public Music createFromParcel(Parcel in)
{
return new Music(in);
}
public Music[] newArray(int size)
{
return new Music[size];
}
};
}
Wenn ich diesen Code ausführe, ist das Problem eine java.lang.NullPointerException in der Fragment onCreateView () -Methode . Ich würde mich sehr freuen, wenn mich jemand in die richtige Richtung weisen würde, um zu sehen, wo ich versage.
BEARBEITEN : Problem gelöst: Ich musste nur diese Zeile zur Fragment Activity onCreate () -Methode hinzufügen (andernfalls würde getArguments () null zurückgeben):
getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, frag).commit();
Und fügen Sie dies dem Fragmentcode hinzu:
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
Bundle bundle = getArguments();
if(bundle != null)
{
listMusics = bundle.getParcelableArrayList("arrayMusic");
listMusic.setAdapter(new MusicBaseAdapter(getActivity(), listMusics));
}
}
wo ist listMusics ein ArrayList
von Parcelable
Musik.
quelle
Antworten:
Zwei Dinge. Erstens glaube ich nicht, dass Sie die Daten, die Sie an das Fragment übergeben möchten, korrekt hinzufügen. Was Sie an das Fragment übergeben müssen, ist ein Bündel, keine Absicht. Wenn ich beispielsweise einen
int
Wert an ein Fragment senden möchte, würde ich ein Bundle erstellen, dasint
in dieses Bundle einfügen und dieses Bundle dann als Argument festlegen, das beim Erstellen des Fragments verwendet werden soll.Zweitens, um diese Informationen abzurufen, müssen Sie die Argumente an das Fragment senden lassen. Anschließend extrahieren Sie den Wert basierend auf dem Schlüssel, mit dem Sie ihn identifiziert haben. Zum Beispiel in Ihrem Fragment:
Was Sie bekommen, ändert sich je nachdem, was Sie setzen. Auch der Standardwert ist normalerweise
null
, muss aber nicht sein. Dies hängt davon ab, ob Sie einen Standardwert für dieses Argument festlegen.Schließlich glaube ich nicht, dass Sie dies in tun können
onCreateView
. Ich denke, Sie müssen diese Daten innerhalb deronActivityCreated
Methode Ihres Fragments abrufen . Meine Argumentation ist wie folgt.onActivityCreated
wird ausgeführt, nachdem die zugrunde liegende Aktivität ihre eigeneonCreate
Methode beendet hat. Wenn Sie die Informationen, die Sie abrufen möchten,onCreate
während der Methode Ihrer Aktivität in das Bundle einfügen , sind sie während der Fragmente nicht vorhandenonCreateView
. Versuchen Sie dies inonActivityCreated
und aktualisieren Sie IhreListView
Inhalte später.quelle
Parcelable
Schnittstelle implementieren .Bundle
unterstützt das Hinzufügen / AbrufenParcelable
so dass Sie diese auch problemlos senden können.Ich bevorzuge
Serializable
= kein Boilerplate-Code. Für die Übergabe von Daten an andere Fragmente oder Aktivitäten spielt der Geschwindigkeitsunterschied zu aParcelable
keine Rolle.Ich würde auch immer eine Hilfsmethode für a bereitstellen
Fragment
oder aufActivity
diese Weise immer wissen, welche Daten übergeben werden müssen. Hier ein Beispiel für IhreListMusicFragment
:quelle
Es gibt einen einfachen Grund, warum ich das Bundle aufgrund der fehlenden doppelten Daten im Speicher vorgezogen habe. Es besteht aus einer öffentlichen init-Methode für das Fragment
Mit zwei Worten, Sie erstellen eine Instanz des Fragments und übergeben mit der init-Methode (Sie können es wie gewünscht aufrufen) die Referenz Ihrer Liste, ohne eine Kopie durch Serialisierung an die Instanz des Fragments zu erstellen. Dies ist sehr nützlich, denn wenn Sie etwas in der Liste ändern und es in den anderen Teilen der App erhalten, verbrauchen Sie natürlich weniger Speicher.
quelle
newInstance
undsetArguments
wie empfohlen.tolle Antwort von @Rarw. Versuchen Sie, mithilfe eines Bundles Informationen von einem Fragment an ein anderes zu übergeben
quelle