I have a view pager activity in an android app that I want to use to navigate a collection of typed objects. The first one loads fine, but when you swipe to navigate, the content of the child fragment doesn't get repopulated. Code as follows.
Ps - if you look at the last XML file below, you can see what is being used as the pager source fragment. All the other buttons re-appear fine as you re-page. It is only the FrameLayout child frame that doesn't reload.
public class FindActivity
{
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_find);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
ArrayList<MyItem> items = new ArrayList<MyItem>();
items.add(new MyItem("James", 34, "London", R.drawable.profile, R.drawable.camera, "What does this photo make you think of?", R.drawable.ocean));
mCollectionPagerAdapter = new CollectionPagerAdapter(getApplicationContext(), getFragmentManager(), items);
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mCollectionPagerAdapter);
....
}
public class CollectionPagerAdapter extends FragmentStatePagerAdapter {
private ArrayList<MyItem> items;
private Context context;
public CollectionPagerAdapter(Context context, FragmentManager fm, ArrayList<MyItem> itemCollection)
{
super(fm);
items = itemCollection;
this.context = context;
}
@Override
public Fragment getItem(int position) {
Fragment fragment = new MyItemPagerFragment(context);
Bundle args = new Bundle();
args.putString(MyItemPagerFragment.ARG_USERNAME, items.get(position).Name);
args.putInt(MyItemPagerFragment.ARG_AGE, items.get(position).Age);
args.putString(MyItemPagerFragment.ARG_LOCATION, items.get(position).Location);
args.putInt(MyItemPagerFragment.ARG_PROFILEIMAGE, items.get(position).ProfileImage);
args.putInt(MyItemPagerFragment.ARG_GENREIMAGE, items.get(position).GenreImage);
args.putString(MyItemPagerFragment.ARG_DESCRIPTION, items.get(position).Description);
args.putInt(MyItemPagerFragment.ARG_CONTENTIMAGE, items.get(position).ContentImage);
fragment.setArguments(args);
return fragment;
}
@Override
public int getCount() {
return items.size();
}
@Override
public CharSequence getPageTitle(int position) {
return "Item: " + items.get(position).Name;
}
}
public class MyItemPagerFragment extends Fragment {
public static final String ARG_USERNAME = "name";
public static final String ARG_AGE = "age";
public static final String ARG_LOCATION = "location";
public static final String ARG_PROFILEIMAGE = "profileimage";
public static final String ARG_GENREIMAGE = "genreimage";
public static final String ARG_DESCRIPTION = "description";
public static final String ARG_CONTENTIMAGE = "contentimage";
private Context context;
public MyItemPagerFragment(Context context)
{
this.context = context;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_find, container, false);
Fragment fragment = new ItemFragment(
getArguments().getString(ARG_USERNAME),
getArguments().getInt(ARG_AGE),
getArguments().getString(ARG_LOCATION),
context.getResources().getDrawable(getArguments().getInt(ARG_PROFILEIMAGE)),
context.getResources().getDrawable(getArguments().getInt(ARG_GENREIMAGE)),
getArguments().getString(ARG_DESCRIPTION),
context.getResources().getDrawable(getArguments().getInt(ARG_CONTENTIMAGE)));
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.find_content, fragment).commit();
return rootView;
}
}
And fragment_find.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="lakecrest.FindActivity$PlaceholderFragment" >
<FrameLayout
android:id="@+id/find_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
/>
<LinearLayout
android:layout_below="@id/find_content"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/sendmessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/button_startconversation"
style="?android:attr/borderlessButtonStyle" />
</LinearLayout>
<LinearLayout
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/addtobasket"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/button_basket"
style="?android:attr/borderlessButtonStyle" />
<ImageButton
android:id="@+id/notinterested"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_cancel"
style="?android:attr/borderlessButtonStyle"/>
</LinearLayout>
</RelativeLayout>
I presume that ItemFragment
and MyItemPagerFragment
are two different fragment types, with the former nested inside the latter.
In that case, try this: in the onCreateView()
method of your MyItemPagerFragment
class, replace
FragmentManager fragmentManager = getFragmentManager();
with
FragmentManager fragmentManager = getChildFragmentManager();
First test your app with this modification. If you experience an IllegalStateException
getting thrown, then add the following code to your MyItemPagerFragment
class:
@Override
public void onDetach() {
super.onDetach();
try {
Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
If you don't experience any crashes after the first modification, then ignore the second one.