I am new to using a ViewPager, but the initial screen on my app is a ListView that the user can add/remove new items to, then clicking on one of the items brings them to a “details” fragment based on an id that is passed. I’d like for the user to also be able to swipe from the listing through to each of the details.
I have the ViewPager working, except the id’s are always off by one. This might be my lack of understanding of ViewPagers, but if I put a breakpoint in the onCreateView of the details fragment, the breakpoint is hit when the app loads and the id that is passed is the first id. So, say the ids are 1,2,3,4, when the app loads, the id on app start-up in onCreateView is 1. When I perform the initial swipe from the listing to the first details fragment, the id is 2 (when I would expect it to be 1).
This is what I have so far:
Main.class (this initial activity on app start-up)
public class Main extends SherlockFragmentActivity
{
private static int NUMBER_OF_PAGES;
private ViewPager mViewPager;
private MyFragmentPagerAdapter mMyFragmentPagerAdapter;
private static List<Fragment> fragments;
@Override
public void onCreate(final Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.main);
mViewPager = (ViewPager)findViewById(R.id.viewpager);
mMyFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mMyFragmentPagerAdapter);
final List<Integer> ids = GetIds(); //loads ids to popular the viewpager
NUMBER_OF_PAGES = ids.size();
fragments = new ArrayList<Fragment>();
fragments.add(new ListingFragment()); //initial screen
for(Integer id : ids)
fragments.add(DetailsFragment.newInstance(id));
}
private static class MyFragmentPagerAdapter extends FragmentStatePagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
return fragments.get(index);
}
@Override
public int getCount() {
return NUMBER_OF_PAGES;
}
}
}
DetailsFragment.class
public class DetailsFragment extends SherlockFragmentActivity
{
private int detailId;
private List<Integer> items;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@Override
public void onActivityCreated(final Bundle icicle)
{
super.onActivityCreated(icicle);
}
public static DetailsFragment newInstance(int id) {
DetailsFragment lf = new DetailsFragment();
Bundle bundle = new Bundle();
bundle.putInt("id", id);
lf.setArguments(bundle);
return lf;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.details, container, false);
detailId = getArguments().getInt("id"); //this id is always off
items = GetItems();
return view;
}
}
Maybe I don’t understand the problem you’re facing but the code you posted(again, if that is the full code you use(currently it will not compile as your
DetailsFragmentsextendsSherlockFragmentActivity(?!))) can’t do what you say. The way you setup the fragments will make the them have the proper ids.What you’re seeing it’s most likely due to the way the
ViewPagerworks, which can be misleading. When you first start the app you’ll see theListingFragment. Now, theViewPager, in order to provide a smooth swipe for the user will also load(by default) one additional fragment on each side of the current visible fragment(so when the app starts theViewPagerwill load page0(ListingFragment) and the next(to the right as we don’t have anywhere to go left)) page,1(theDetailsFragmentwith the id1). When you swipe from theListingFragmentto the firstDetailsFragment(which has the id1) theViewPagerwill automatically create the secondDetailsFragment(which has the id2) in advance(again, in order to be able to swipe right away to it). Now, if you have aLogstatement in theonCreateViewin theDetailsFragment(to see theid) it’s normal that you see the second id as you swipe from theListingFragmentto the firstDetailsFragmentbecause thatLogwill not appear from the firstDetailsFragment(with id1, which is already created) being created, it will appear because the secondDetailsFragment(with id2) is being created in advance.Also, revise your code, as you introduced a subtle bug. You set the size of the adapter to
NUMBER_OF_PAGESwhich is initialized withids.size()but then you add theListingFragmentwhich will make theDetailsFragmentwith the last id(fromids) not appear at all.