Paul S Paul S - 4 months ago 12
Android Question

Setting an Array that belongs to a fragment from the main activity

EDIT 2: Fragment Adapter:

public class PageAdapter extends FragmentStatePagerAdapter {
ArrayList<Song> songList; //Update
public PageAdapter(FragmentManager fm) {
super(fm);
}

@Override
public Fragment getItem(int i) {
switch (i) {
case 0:
return MusicList.newInstance(songList); //Update
}
return null;
}

@Override
public int getCount() {
return 1; //No of Tabs
}
}


EDIT: id.music_list_fragment(layout.fragment_main) Layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/music_list_fragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="@drawable/headphones">

<ListView
android:id="@+id/song_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="true">
</ListView>

</LinearLayout>


I'm trying to send an Array list from the activity "MainActivity" to its fragment "MusicList" by replacing the fragment.

By using this in the activity:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment fragment = MusicList.newInstance(songList);
ft.replace(R.id.music_list_fragment, fragment);
ft.commit();


And using this in the fragment:

public static MusicList newInstance(ArrayList<Song> songList) {
MusicList fragment = new MusicList();
Bundle bundle = new Bundle();
bundle.putSerializable(DESCRIBABLE_KEY, songList);
fragment.setArguments(bundle);

return fragment;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_main, container, false);
mList = ((ListView)v.findViewById(R.id.song_list));
msongList = (ArrayList<Song>) getArguments().getSerializable(DESCRIBABLE_KEY);
SongAdapter sAdapter = new SongAdapter(getActivity(), msongList);
mList.setAdapter(sAdapter);

return v;
}


And I'm getting this error:

java.lang.RuntimeException: Unable to start activity ComponentInfo{pal.mplayercomeon/pal.mplayercomeon.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f0c0074 (pal.mplayercomeon:id/music_list_fragment) for fragment MusicList{ee972d3 #0 id=0x7f0c0074}
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f0c0074 (pal.mplayercomeon:id/music_list_fragment) for fragment MusicList{ee972d3 #0 id=0x7f0c0074}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1059)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:339)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:601)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1248)
at android.app.Activity.performStart(Activity.java:6681)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2609)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6077) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 

Answer
  1. You need to initialize an ArrayList before you pass to the Fragment newInstance method, otherwise it is null.
  2. You are using a PagerAdapter, so you add that to a ViewPager. You do not need a FragmentTransaction, so that code is irrelevant. The getCount method of the adapter loads that many Fragments in the ViewPager.
  3. Follow-up on 2, this is not right ... ft.replace(R.id.music_list_fragment, fragment);, unless android:id="@+id/music_list_fragment" is contained as a FrameLayout inside of the Activity XML, not the Fragment XML. But, as stated, you seem to want to use a ViewPager

Additional point - Song needs to implement Serializable, however, you really should be using Parcelable because that is the preferred way to pass data in Android.

Comments