Android:将数据(额外)传递给一个片段

我是Android编程新手,在将一个Parcelable的ArrayList传递给一个片段时遇到了问题。 这是启动的Activity(运行良好!),其中feedlist是可分段音乐的ArrayList。

Intent in = new Intent(context, ListMusicsActivity.class); in.putExtra("arrayMusic", feedList); activity.startActivity(in); 

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

代码片段:

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

我认为问题是在线

 listMusics = (ArrayList<Music>) getArguments().getSerializable("arrayMusic"); 

最后这是我的音乐课:

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

当我运行这个代码时,我得到的问题是在片段onCreateView()方法中java.lang.NullPointerException 。 如果有人指出我在正确的方向看我失败的地方,我将非常感激。

编辑 :解决的问题:我只需要添加此行的片段Activity的onCreate()方法(否则getArguments()将返回null):

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

并将其添加到片段代码中:

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

其中,listMusics是一个Parcelable Music的ArrayList

两件事情。 首先,我不认为你正在添加你想传递给片段的数据。 你需要传递给片段的是一个包,而不是一个意图。 例如,如果我想发送一个int值到一个片段,我会创build一个包,把int放入该包,然后将该包设置为在创build片段时使用的参数。

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

其次,要获取这些信息,您需要获取发送到片段的参数。 然后,根据您确定的密钥提取值。 例如在你的片段中:

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

你得到的变化取决于你所做的。 此外,默认值通常为null但不需要。 这取决于你是否为该参数设置了一个默认值。

最后我不认为你可以在onCreateView做到这一点。 我认为你必须检索你的片段的onActivityCreated方法中的这个数据。 我的推理如下。 onActivityCreated在基础活动完成自己的onCreate方法后运行。 如果你在你的activity的onCreate方法中放置你希望检索的信息,那么在片段的onCreateView期间它不会存在。 尝试在onActivityCreated使用这个,稍后更新您的ListView内容。

我更喜欢Serializable =没有样板代码。 为了将数据传递给其他片段或活动,与Parcelable的速度差异无关紧要。

我也总是提供一个FragmentActivity的辅助方法,这种方式,你总是知道,什么数据必须通过。 这里是一个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); ... } 

有一个简单的原因,由于内存中没有重复的数据,我喜欢捆绑。 它由片段的init公共方法组成

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

换句话说,你可以通过init方法创build一个片段的实例(你可以调用它,就像你想的那样),而不是通过序列化来创build片段的实例。 这是非常有用的,因为如果你改变列表中的东西,你会得到它在应用程序的其他部分,当然,你使用更less的内存。

@Rarw很好的回答。 尝试使用包将信息从一个片段传递到另一个片段