2013-03-13 8 views
66

私はAndroidプログラミングが初めてで、ParcelableのArrayListをフラグメントに渡している間に問題が発生しています。 フィードリストは、パーセル化可能な配列のリスト音楽です。これは、開始されたアクティビティです(正常に動作しています)。Android:データ(エキストラ)をフラグメントに渡す

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

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

断片アクティビティの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があります。 誰かが正しい方向に私を指摘して私がどこに失敗しているかを知っていれば、私は多くのことを感謝するでしょう。

EDIT:問題が解決:

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

とフラグメントにこれを追加します。私はちょうど(getArguments othwewise()はnullを返します)フラグメント活動のonCreate()メソッドに次の行を追加する必要がコードは:

@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音楽のArrayListです。

+0

最初のステップでは、LogCatウィンドウを開き、例外を見て、NullPointerExceptionの原因を確認します。あなたがそれを理解できない場合は、誰かが助けることができるあなたの質問に例外からスタックトレースを入れてください。 – Brian

+0

BrianV:チップをありがとう!ここで私はプログラムを実行すると私が得るLogCatです! http://pastebin.com/ycVcXLFf – pluralism

+0

ビューレイアウトファイルにエラーがあるようです:**原因:android.view.InflateException:バイナリXMLファイル行#10:クラスフラグメントを拡張するエラー** – Brian

答えて

157

2つのもの。まずは、フラグメントに渡すデータを正しく追加しているとは思わない。フラグメントに渡す必要があるのは、意図ではなくバンドルです。たとえば、intの値をフラグメントに送りたい場合は、バンドルを作成し、intをそのバンドルに入れ、フラグメントが作成されたときに使用する引数としてそのバンドルを設定します。

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

第2に、その情報を取得するには、引数をフラグメントに送信する必要があります。次に、それを識別したキーに基づいて値を抽出します。たとえば、あなたの断片の中で:

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

あなたは何を入れているかによって変わります。また、デフォルト値は通常nullですが、そうである必要はありません。この引数のデフォルト値を設定するかどうかによって異なります。

最後に、onCreateViewでこれを行うことはできません。あなたのフラグメントのonActivityCreatedメソッド内でこのデータを取得する必要があると思います。私の推論は次の通りです。 onActivityCreatedは、基本アクティビティが独自のonCreateメソッドを終了した後に実行されます。アクティビティのonCreateメソッドの実行中にバンドル内で取得する情報を配置する場合は、フラグメントのonCreateViewの間は存在しません。onActivityCreatedでこれをお試しください。後ほどListViewの内容を更新してください。

+3

シンプルな答え、素晴らしい。あなたのコード例をコピーし、それは治療を働いた! – iamanyone

+1

...引数がプリミティブではなく特定のインターフェイスを実装しているオブジェクトによって指定されている場合はどうなりますか? – Piotr

+2

オブジェクトを使いたい場合は、それらが 'Parcelable'インタフェースを実装していることを確認してください。 'Bundle'は' Parcelable'の追加/取得をサポートしているので、問題なく送信することができます。 – Rarw

1

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); 
    ... 
} 
1

シンプルがあります。それはあなたがすることなく、あなたのリストの参照を渡す(uがしたいとuはそれを呼び出すことができます)フラグメント

二つの単語で
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 publicメソッドで構成され、あなたがinitメソッドによりフラグメントANのインスタンスを作成しますフラグメントのインスタンスへのシリアル化によってコピーを作成します。これは非常に便利です。あなたがリストの中の何かを変更すると、アプリケーションの他の部分でそれを取得し、メモリを少なくしてしまうからです。

+0

Androidでは間違った方法です。フラグメントの再作成時(構成の変更(画面の回転)など)には空のコンストラクタが呼び出され、すべてのパラメータが失われるためです。推奨されるように 'newInstance'と' setArguments'を使用してください。 – CoolMind

-2

素晴らしい回答@Rarw。バンドルを使用して、あるフラグメントから別のフラグメントに情報を渡してみてください。

関連する問題