سؤال

I have main fragment and Viewpager with 3 pages in this fragment(1). In main fragment(1) i choose city and acording to the value of the city main fragment(1) loads data from server and pass in to FragmentPagerAdapter. At first time everything is ok but if i choose another city(2) the data in viewpager updates only after sliding pages from one side to another.

So if i choose another sity at first i see blank page 1, after sliding forward to page 2 and 3 and returning to page 1 the data updates on 1 and 3 page but the 2 page is empty.

So i don`t get where is the error? thanks

here is my FragmentStatePagerAdapter code

 private class MyPagerAdapter extends FragmentStatePagerAdapter {

    public MyPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getItemPosition(Object object) {
        Log.d("getItemPosition","123");
        return POSITION_NONE;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        Resources res = getResources();
        String[] title = res.getStringArray(R.array.title_spa_viewpager_array);
        return title[position];
    }

    @Override
    public android.support.v4.app.Fragment getItem(int pos) {
        switch(pos) {
            case 0: return FirstFragment.newInstance(mSpa.getSpaName()+SpaInfoParserObject.MySpaInfo.getSpaInfoText());
            case 1: return SecondFragment.newInstance("",SpaInfoParserObject.MySpaInfo);
            case 2: return PhotoFragment.newInstance("", SpaInfoParserObject.MySpaInfo.getSpaInfoPic(), mSpa);
            default: return FirstFragment.newInstance(mSpa.getSpaPhone());
        }
    }

    @Override
    public int getCount() {
        return 3;
    }
}
هل كانت مفيدة؟

المحلول

There are two main problems with your code.

First of all I had a look at one of your previous question and I saw that you use:

FragmentManager f = ((FragmentActivity) getActivity()).getSupportFragmentManager();

to initialize the adapter of the ViewPager. This is incorrect, if you embed the ViewPager(along with its fragments which become nested fragments) in another Fragment then you must use the FragmentManager returned by the getChildFragmentManager() method(of the Fragment class) instead of the line above. If you already use getChildFragmentManager() ignore this part otherwise change the code to use it.

Secondly, updating the fragments of a ViewPager has been discussed before(although you use nested fragment its the same process) and you need to take in consideration two cases in which the ViewPager's fragments might be:

  • the fragment is either the current visible fragment or the closest fragment on the left/right side of the visible fragment(for example, if position 0 is the current one visible you'll have two fragments in memory: position 0 and position 1). This fragments have their views built and are ready to be shown to the user and you need to update their data/views directly(by calling some setter methods for example). To easiest way to access this fragment is to use the code in this question (which is very related, also note that you're using nested fragments so getFragmentManager() will be replaced by getChildFragmentManager())

  • any other position than the one above. To handle this case you should make each fragment from the ViewPager to retrieve the data(which will reflect the new data changes) in their onCreateView() which will be called if the user swipes towards that fragment. Some sample code:

    // in the onCreateView()
    YourParentFragmentClass parent = (YourParentFragmentClass) getParentFragment();
    // parent is the Fragment holding the ViewPager and you can use further use it to
    // get data
    

    Every fragment from the ViewPager should have this piece of code to handle the data update. For example, if you swipe to the third fragment and then update the data, you should directly update fragments 2 and 3. Fragment 1 however will be updated when the ViewPager will recreate its view(when the user swipes from fragment 3 to fragment 2), at that moment the above piece of code will get the new data from the parent fragment which will be the latest one.

You also will not need to pass the data as arguments in that newInstance() method.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top