我是Android编程的新手,在将Parcelable的ArrayList传递给片段时遇到了问题。 这是推出的活动(效果很好!),其中 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];
}
};
}
当我运行此代码时,我得到的问题是Fragment 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是ArrayList
音乐的Parcelable
。
答案 0 :(得分:176)
两件事。首先,我不认为您正在添加要正确传递给片段的数据。您需要传递给片段的是捆绑,而不是意图。例如,如果我想向片段发送int
值,我会创建一个包,将int
放入该包中,然后将该包设置为在创建片段时使用的参数。
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
方法后运行。如果您在活动的onCreate
方法中放置要在包中检索的信息,则在您的片段onCreateView
期间它将不存在。请尝试在onActivityCreated
中使用此功能,稍后再更新您的ListView
内容。
答案 1 :(得分:2)
我更喜欢Serializable
=没有样板代码。将数据传递给其他片段或活动the speed difference to a Parcelable
并不重要。
我也总是为Fragment
或Activity
提供帮助方法,这样你总能知道,必须传递什么数据。这是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 :(得分:1)
由于内存中没有重复数据,有一个简单的原因我更喜欢捆绑。它由片段的
的init公共方法组成#<Rda:0xf6e8a0c
id: 1,
age_group: "18-100",
weight: "60",
nutrient: "energy(kcal/day)",
value: "2730",
created_at: Sat, 15 Oct 2016 08:21:43 UTC +00:00,
updated_at: Sat, 15 Oct 2016 08:21:43 UTC +00:00>
#<Rda:0xf6e8a0c
id: 2,
age_group: "10-15",
weight: "60",
nutrient: "energy(kcal/day)",
value: "2730",
created_at: Sat, 15 Oct 2016 08:21:43 UTC +00:00,
updated_at: Sat, 15 Oct 2016 08:21:43 UTC +00:00>
#<Rda:0xf6e8a0c
id: 3,
age_group: "20-100",
weight: "60",
nutrient: "energy(kcal/day)",
value: "2730",
created_at: Sat, 15 Oct 2016 08:21:43 UTC +00:00,
updated_at: Sat, 15 Oct 2016 08:21:43 UTC +00:00>
简而言之,您可以通过init方法创建片段的实例(您可以根据需要调用它),您可以传递列表的引用,而无需通过序列化创建片段实例的副本。这非常有用,因为如果您更改列表中的某些内容,您将在应用程序的其他部分和当前部分中获得它,您将使用更少的内存。
答案 3 :(得分:-4)