2

In my project I have a tab layout and a fragments viewpager. When I load the fragments and tabs the tab index and the displayed fragment is out of sync, and also when I swipe back and forth the fragments are not in sync with the tabs. I checked the getItem(int position) and the getTitle(int position) methods both have the same position number and the corresponding entries in the ArrayList<Fragments> and the ArrayList<String> (for tab headings) are correct but some how the tabs display is out of sync with the view pager.

Here is my fragmentPagerAdapter.java

    public class DetailsFragmentPagerAdapter extends FragmentPagerAdapter {

    private ArrayList<Fragment> fragments;
    private ArrayList<String> titles;

    public DetailsFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
        fragments = new ArrayList<>();
        titles = new ArrayList<>();
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        return titles.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return titles.get(position);
    }

    public void setFragment(Fragment fragment, String title) {
        fragments.add(fragment);
        titles.add(title);
        notifyDataSetChanged();
    }
}

this is activity on create.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_details);
    tabLayout = (TabLayout) findViewById(R.id.detailsTabs);
    viewPager = (ViewPager) findViewById(R.id.viewPager);
    new GetCategoriesAsync2().execute();
}

the async task's doInBackground is calling is preparing arraylist

and the onPostExecute

@Override
    protected void onPostExecute(Void aVoid) {
        int size = lists.size();
        ArrayList<Fragment> fragments = new ArrayList<>(size);
        ArrayList<String> titles = new ArrayList<>(size);
        for (int i = 0; i < lists.size(); i++) {
            ArrayList<String> x = lists.get(i);
            titles.add(x.remove(0));
            fragments.add(DetailsListFragment.newInstance(x));
        }
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentPagerAdapter = new DetailsFragmentPagerAdapter(fragmentManager);
        fragmentPagerAdapter.setFragments(fragments,titles);
        viewPager.setAdapter(fragmentPagerAdapter);
        tabLayout.setupWithViewPager(viewPager);
        progressDialog.dismiss();
    }

I am using design support library 23.0.1 and the build target is 23. how can I fix this tab layout out of sync?

Sony
  • 7,136
  • 5
  • 45
  • 68

3 Answers3

2

if you use a TabLayout, you need to connect it to the adapter

If you're using a ViewPager together with this layout, you can use setTabsFromPagerAdapter(PagerAdapter) which will populate the tabs using the given PagerAdapter's page titles. You should also use a TabLayout.TabLayoutOnPageChangeListener to forward the scroll and selection changes to this layout like so:

ViewPager viewPager = ...;
 TabLayout tabLayout = ...;
 viewPager.addOnPageChangeListener(new TabLayoutOnPageChangeListener(tabLayout));
bwt
  • 17,292
  • 1
  • 42
  • 60
  • can you make that clear. I mean how to select the correct tabs and fragments inside the listener. a pseudo code or a brief will be more than enough – Sony Dec 21 '15 at 09:59
  • This is exactly what `tabLayout.setupWithViewPager(viewPager);` does (as seen in your updated question). So they should be connected. – bwt Dec 21 '15 at 11:35
  • By the way the `setFragments(list)` (in `onPostExecute`) does not seems to match `setFragment(one fragment)` (in the adapter) – bwt Dec 21 '15 at 11:38
0

Try this, it worked for me

public class DetailsFragmentPagerAdapter extends FragmentPagerAdapter {

private final List<Fragment> fragments= new ArrayList<Fragment>();

private final List<String> titles= new ArrayList<String>();

public DetailsFragmentPagerAdapter(FragmentManager fm) {
    super(fm);

}

@Override
public Fragment getItem(int position) {
    return fragments.get(position);
}

@Override
public int getCount() {
    return fragments.size();
}

@Override
public CharSequence getPageTitle(int position) {
    return titles.get(position);
}

public void setFragment(Fragment fragment, String title) {
    fragments.add(fragment);
    titles.add(title);

}
}

And Change
fragmentPagerAdapter.setFragments(fragments,titles); To

  for (int i=0;i<fragments.size();i++)
  {
    adapter.setFragments(fragments.get(i),titles.get(i));   
  }
Nisarg
  • 1,358
  • 14
  • 30
0

Check this out

it's a demo app that uses a TabLayout with a ViewPager

https://github.com/chrisbanes/cheesesquare

and if you don't know the number of the fragments that you will have in the ViewPager

your pageadapter should extends FragmentStatePagerAdapter

https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html

Mark
  • 47
  • 2
  • 13