Android: Przekazywanie danych (dodatków) do fragmentu

Jestem nowy w programowaniu Androida i mam problemy podczas przekazywania ArrayList z Parcelable do fragmentu. Jest to działalność, która jest uruchomiona (działa dobrze!) gdzie feedlist jest Arraylistą parcelowanej muzyki.

Intent in = new Intent(context, ListMusicsActivity.class);

in.putExtra("arrayMusic", feedList);
activity.startActivity(in);

Metoda fragment Activity onCreate ():

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activitymusiclist);

    if(savedInstanceState != null)
    {
        ListMusicFragment frag = new ListMusicFragment();
        frag.setArguments(getIntent().getExtras());
    }
}

Kod fragmentu:

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;
}
}

Myślę, że problem jest w linii

listMusics = (ArrayList<Music>) getArguments().getSerializable("arrayMusic");
W końcu to moja klasa Muzyczna:
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];
    }
};
}

Kiedy uruchamiam ten kod problem jaki mam to java.lang.NullPointerException w metodzie Fragment onCreateView () . Byłbym bardzo wdzięczny, gdyby ktoś wskazał mi właściwy kierunek, aby zobaczyć, gdzie zawodzę.

EDIT : Problem rozwiązany: po prostu musiałem dodać tę linię do metody fragment Activity onCreate () (w przeciwnym razie getArguments () zwróci null):

getSupportFragmentManager().beginTransaction()
    .add(android.R.id.content, frag).commit();

I dodaj to do kodu fragmentu:

@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));
    }
}

Gdzie, listMusics jest ArrayList z Parcelable muzyki.

Author: Anus Kaleem, 2013-03-13

4 answers

Dwie rzeczy. Po pierwsze myślę, że nie dodajesz poprawnie danych, które chcesz przekazać do fragmentu. To, co musisz przekazać fragmentowi, to paczka, a nie intencja. Na przykład, gdybym chciał wysłać wartość int do fragmentu, utworzyłbym pakiet, umieścił int w tym pakiecie, a następnie ustawił ten pakiet jako argument, który będzie używany podczas tworzenia fragmentu.

Bundle bundle = new Bundle();
bundle.putInt(key, value);
fragment.setArguments(bundle);

Po drugie, aby odzyskać te informacje, musisz pobrać argumenty wysłane do fragmentu. Ty więc wyodrębnij wartość na podstawie klucza, z którym ją zidentyfikowałeś. Na przykład w Twoim fragmencie:

Bundle bundle = this.getArguments();
if (bundle != null) {
    int i = bundle.getInt(key, defaulValue);
}

Co dostajesz zmienia się w zależności od tego, co umieścić. Również domyślną wartością jest zwykle null, ale nie musi być. To zależy od tego, czy ustawisz wartość domyślną dla tego argumentu.

W końcu nie sądzę, że możesz to zrobić w onCreateView. Myślę, że musisz odzyskać te dane w metodzie onActivityCreated twojego fragmentu. Moje rozumowanie jest następujące. onActivityCreated działa po tym, jak podstawowa aktywność ma zakończył własną metodę onCreate. Jeśli umieszczasz informacje, które chcesz pobrać w pakiecie podczas wykonywania swojej aktywności onCreate, nie będą one istniały podczas wykonywania twojego fragmentu onCreateView. Spróbuj użyć tego w onActivityCreated i zaktualizuj swoją zawartość ListView później.

 168
Author: Rarw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-09 15:43:41

Wolę Serializable = Brak kodu kotła. Do przekazywania danych do innych fragmentów lub działań różnica prędkości do Parcelable nieważne.

Zawsze podałbym również metodę pomocniczą dla Fragment lub Activity, w ten sposób zawsze wiesz, jakie dane należy przekazać. Oto przykład twojego ListMusicFragment:

private static final String EXTRA_MUSIC_LIST = "music_list";

public static ListMusicFragment createInstance(List<Music> music) {
    ListMusicFragment fragment = new ListMusicFragment();
    Bundle bundle = new Bundle();
    bundle.putSerializable(EXTRA_MUSIC_LIST, music);
    fragment.setArguments(bundle);
    return fragment;
}

@Override
public View onCreateView(...) { 
    ...
    Bundle bundle = intent.getArguments();
    List<Music> musicList = (List<Music>)bundle.getSerializable(EXTRA_MUSIC_LIST);
    ...
}
 2
Author: artkoenig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-15 10:41:19

Jest proste, dlaczego wolałem pakiet ze względu na brak duplikatów danych w pamięci. Składa się z publicznej metody init dla fragmentu

private ArrayList<Music> listMusics = new ArrayList<Music>();
private ListView listMusic;


public static ListMusicFragment createInstance(List<Music> music) {
    ListMusicFragment fragment = new ListMusicFragment();
    fragment.init(music);
    return fragment;
}

public void init(List<Music> music){
    this.listMusic = music;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
    Bundle savedInstanceState)
{

    View view = inflater.inflate(R.layout.musiclistview, container, false);
    listMusic = (ListView) view.findViewById(R.id.musicListView);
    listMusic.setAdapter(new MusicBaseAdapter(getActivity(), listMusics));

    return view;
}
}

W dwóch słowach tworzysz instancję fragmentu przy pomocy metody init (możesz ją nazwać jak chcesz) przekazujesz referencję swojej listy bez tworzenia kopii przez serializację do instancji fragmentu. Jest to bardzo przydatne, ponieważ jeśli zmienisz coś na liście u dostanie go w innych częściach aplikacji i oczywiście, zużywasz mniej pamięci.

 1
Author: Ivan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-15 10:47:49

Świetna odpowiedź przez @ Rarw. Spróbuj użyć pakietu, aby przekazać informacje z jednego fragmentu do drugiego

 -3
Author: masterwambua,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-17 17:22:36