Viewpager shows wrong page
Asked Answered
U

2

6

I have a viewpagerindicator by Jake Wharton and in that viewpager i have 6 pages.All of the pages contains listviews and i'm loading them with an AsyncTask.Sometimes viewpager shows wrong pages at wrong indexes.Here is my viewpager adapter:

public class TestFragmentAdapter extends FragmentPagerAdapter{
    protected static final String[] CONTENT = new String[] { "a","b","c","d","e","f" };

    private int mCount = CONTENT.length;
    Fragment fragment1,fragment2,fragment3,fragment4,fragment5,fragment6;

    public TestFragmentAdapter(FragmentManager fm) {
        super(fm);
        fragment1 = new CategoryListView();
        fragment2 = CustomizedListviewRecent.newInstance(41);
        fragment3 = CustomizedListviewMostRecents.newInstance(0);
        fragment4 = CustomizedListviewPopulars.newInstance();
        fragment5 = CustomizedListviewRecent.newInstance(42);
        fragment6 = CustomizedListviewRecent.newInstance(43);

    }

    @Override
    public Fragment getItem(int position) {
        if(position == 0)
            return fragment1;
        else if(position == 1)
            return fragment2;
        else if(position == 2)
            return fragment3;
        else if(position == 3)
            return fragment4;
        else if(position == 4)
            return fragment5;
        else
            return fragment6;
    }
    @Override
    public int getCount() {
        return mCount;
    }

    @Override
    public CharSequence getPageTitle(int position) {
      return TestFragmentAdapter.CONTENT[position % CONTENT.length];
    }

    public void setCount(int count) {
        if (count > 0 && count <= 10) {
            mCount = count;
            notifyDataSetChanged();
        }
    }

}

Here is how i create my viewpager:

public class SampleTitlesDefault extends BaseSampleActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mAdapter = new TestFragmentAdapter(getSupportFragmentManager());

        mPager = (ViewPager)findViewById(R.id.pager);
        mPager.setAdapter(mAdapter);

        mIndicator = (TitlePageIndicator)findViewById(R.id.indicator);
        mIndicator.setViewPager(mPager);
        mIndicator.setCurrentItem(1);
    }

}

What can be problem here?How can i solve this?Thanks for your help

Unctuous answered 26/1, 2013 at 18:47 Comment(9)
I'm having a similar issue! I'm also using ViewPageIndicator and Fragments. Hmmm, what could be the issue here? I'm going to have a look at my code and see what's upWapentake
I removed the ViewPageIndicator from my XML and from my activity code. Problem still persists. My fragment activity seems to confuse which fragment is the current one, and when I try to add an item to a gridview that's on fragment(page) 4 for instance...it gets added to the list on fragment 1 instead. Looking deeper into things hopefully we both can get some help on this one.Wapentake
@JadeByfield Are you using .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) to execute your AsyncTask in your fragments?Unctuous
No, I'm not. I'm not doing any background operations inside my fragments just inflating a gridview and populating it. I have 4 fragments like this, but sometimes when I try to add an item to the gridview of one, it get's added to another!Wapentake
@JadeByfield Is your adapter same with my adapter?Unctuous
Yes, I also use FragmentPagerAdapter. Any suggestions?Wapentake
Try to use:FragmentStatePagerAdapter instead of FragmentPagerAdapter.Also use it like in David's answer.Lastly,override destroyItem like that: public void destroyItem(ViewGroup paramViewGroup, int paramInt, Object paramObject){ super.destroyItem(paramViewGroup, paramInt, paramObject); }Unctuous
Thanks for the tips man. I've switched to now using a FragmentStatePagerAdapter as well as overriding destroyItem...still the same problem. Tinkering around with some stuff to see what's up. Have you solved your problem yet?Wapentake
Hi Anyone got the problem to this solution . ? I also facing the same problem .Page count is not right.Hartebeest
E
3

I know its too late but may be some one need it.

I have also faced the similar problem regarding wrong position and some time it shows same results on two fragments due to wrong positon.I solved my problem by replacing the FragmentPagerAdapter with FragmentStatePagerAdapter

And I also passed index postion from onPageScrolled method using OnPageChangeListener inteface

 viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {


        }

        @Override
        public void onPageSelected(int position) {

            bundle = new Bundle();
            bundle.putInt("position", position);
            primaryFragment.setCurrentPostionAndData(position);

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

Like the docs say, think about it this way. If you were to do an application like a book reader, you will not want to load all the fragments into memory at once. You would like to load and destroy Fragments as the user reads. In this case you will use FragmentStatePagerAdapter. If you are just displaying 3 "tabs" that do not contain a lot of heavy data (like Bitmaps), then FragmentPagerAdapter might suit you well. Also, keep in mind that ViewPager by default will load 3 fragments into memory. The first Adapter you mention might destroy View hierarchy and re load it when needed, the second Adapter only saves the state of the Fragment and completely destroys it, if the user then comes back to that page, the state is retrieved.

Difference between FragmentPagerAdapter and FragmentStatePagerAdapter

Extensive answered 12/5, 2016 at 8:5 Comment(0)
B
0

Please don't "cache" the Fragments yourself because it already does that for you.

That said, you should newInstance them inside the getItem method, and not when creating the adapter. Example:

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

@Override
public Fragment getItem(int position) {
    if(position == 0)
        return new CategoryListView();
    else if(position == 1)
        return CustomizedListviewRecent.newInstance(41);
    else if(position == 2)
        return CustomizedListviewMostRecents.newInstance(0);
    else if(position == 3)
        return CustomizedListviewPopulars.newInstance();
    else if(position == 4)
        return CustomizedListviewRecent.newInstance(42);
    else
        return CustomizedListviewRecent.newInstance(43);
}

Common reasons to do that are:

  1. People think it's more efficient to do it that way; or
  2. A reference to the Fragment may be needed later on.

For (1), as I said, you don't need to worry about it (unless you want to learn it and tweak later, but for now let it be). And if you need (2), then you can do this (originally seen here).

Bloated answered 28/1, 2013 at 1:31 Comment(3)
Thanks for your reply.I also tried that but i'm still having that problem.Is there a bug in ViewPager?Unctuous
Sometimes my first two pages are same.Normally they must have completely different pages.Unctuous
@Unctuous none that I'm aware of. I'd suggest reducing your code and implementing the complexities at each step (improve-test-improve-test-repeat...). Remember that keeping track and changing the count is not even necessary (the adapter class can be much smaller). Hopefully it's not something wrong with your Fragments that look like a problem in the viewpager (e.g., Fragments displaying the same content before your AsyncTasks load them all). Try starting from scratch with demo Fragments and fixed layout contents.Bloated

© 2022 - 2024 — McMap. All rights reserved.