Android ViewPager Loading incorrect fragments
Asked Answered
F

4

6

So I'm trying to get a tab bar and layout underneath my main navigation bar working on my main activity.

I can't seem to get the ViewPager/TabLayout (unsure which is the cause of the problem, new to this) to load the correct fragment. I've read through a ton of documentation and checked more than 1 tutorial to see if I was doing this correctly and it seems that I'm doing the same thing they are...

The OnTabSelectedListener for my TabLayout is seeing the tab changes properly, and in OnTabSelected Im calling viewPager.setCurrentItem(tab.getPosition()) to attempt to set my viewpagers item, but it's still not working. Upon first load, it loads the first and second tabs (I can see via a sent API request from the fragments onCreate methods), and when I click on the other tabs, it consistently loads the wrong fragment, sometimes not even loading one at all!

Not sure if this is related but I'm getting this warning as I switch tabs:

03-03 16:24:22.940 16967-16967/com.sampleapp.app W/FragmentManager: moveToState: Fragment state for BlankFragment3{efddbec #2 id=0x7f0c007b android:switcher:2131492987:2} not updated inline; expected state 3 found 2

I'm using build tools version 23.0.2 and the following dependencies:

compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:support-v4:23.1.1'

This is my layout code for my main nav bar:

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar1"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar2"
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed"
        app:tabGravity="fill"/>

</android.support.design.widget.AppBarLayout>

<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/fab_margin"
    android:src="@android:drawable/ic_input_add" />

</android.support.design.widget.CoordinatorLayout>

As per more than one tutorial, here is the code I'm using for my adapter

public class TabsAdapter extends FragmentPagerAdapter{
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

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

    public void addFrag(Fragment fragment, String title){
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

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

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

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

And here is how I set up my viewpager and tablayout

MainActivity's onCreate:

    ViewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(mViewPager); // Method defined below

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
    tabLayout.setupWithViewPager(mViewPager);
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            mViewPager.setCurrentItem(tab.getPosition());
            Log.w("Tab Selection", String.valueOf(tab.getPosition()));
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

And finally, my setupViewPager method:

private void setupViewPager(ViewPager viewPager) {
    TabsAdapter adapter = new TabsAdapter(getSupportFragmentManager());
    adapter.addFrag(new BlankFragment1(), "One");
    adapter.addFrag(new BlankFragment2(), "Two");
    adapter.addFrag(new BlankFragment3(), "Three");
    viewPager.setAdapter(adapter);
}

If anyone sees anything wrong with this please let me know, I cannot for the life of me get these darn tabs to load the proper fragment.

Thanks ahead of time!

Feverroot answered 3/3, 2016 at 21:10 Comment(5)
Did you debug callbacks onTabUnselected and onTabReselected? Are they work correctly ?Lobscouse
@IgorB unselected is working, but seems reselected isn't getting calledFeverroot
I see in this tutorial developer.android.com/intl/ru/training/implementing-navigation/… . They use FragmentStatePagerAdapter, did you try it ?Lobscouse
I Edited my comment :)Lobscouse
Reference this answer fix viewpager not update in line warningConsultative
C
6

Try with this code mate :D

ViewPager adapter

public class PageAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;

public PageAdapter(FragmentManager fm,int numTabs) {
    super(fm);
    this.mNumOfTabs = numTabs;
}

@Override
public Fragment getItem(int position) {
    switch (position) {
        case 0:
            RemindsTab remindsTab = new RemindsTab();
            return remindsTab;
        case 1:
            TasksTab tasksTab = new TasksTab();
            return tasksTab;
        case 2:
            QuicklyNotesTab quicklyNotesTab = new QuicklyNotesTab();
            return quicklyNotesTab;
        default:
            return null;
    }
}

@Override
public int getCount() {
    return mNumOfTabs;
      } 
   }

and my code in MainActivity for those tabs:

 final TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
    tabLayout.addTab(tabLayout.newTab().setText("Recordatorios"));
    tabLayout.addTab(tabLayout.newTab().setText("Tareas"));
    tabLayout.addTab(tabLayout.newTab().setText("Notas Rapidas"));
    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

     final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
     final PagerAdapter adapter = new PageAdapter(getSupportFragmentManager(),tabLayout.getTabCount());
     viewPager.setAdapter(adapter);
     viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

hope you can solve your issue :)

Cohesion answered 3/3, 2016 at 22:5 Comment(0)
E
4

First of all you have to know how how FragmentPageAdaper works. The FragmentPagerAdapter instantiates two(2) Fragments on start, First index(0) Fragment and Second next index(1) Fragment. So don't try to fight with code, just change your login according to default FragmentPageAdapter work.

1) add this line in Activity

viewPager.setOffscreenPageLimit("your number of fragment"); 

2) add this to your fragment, so you can control fragment action when user switch between pages

  // pause  video and other list when user switch fragment pager
    public void setUserVisibleHint(boolean isVisibleToUser)
    {
        super.setUserVisibleHint(isVisibleToUser);
        if (this.isVisible())
        {
            if (!isVisibleToUser)   // If we are becoming invisible, then...
            {
                mPlayer.pause();

                final SharedPreferences.Editor editor= pref.edit();
                editor.putBoolean("PlayerPause", true);
                editor.putInt("videotime",mPlayer.getCurrentTimeMillis());
                editor.commit();
                Log.e("Video "," serUserVisibleHint not visible to User");//pause or stop video
            }

            if (isVisibleToUser) // If we are becoming visible, then...
            {

              Log.e("Video "," serUserVisibleHint Visible to User");  //play your video
            }
        }
    }
Engross answered 30/9, 2016 at 14:48 Comment(0)
L
1
  1. You don't need to separate in two list view. Try to do it in one class

add class

class FragmentHolder{
    Fragment fragment;
    String title;

    public FragmentHolder(Fragment fragmentm String title){
        this.fragment = fragment;
        this.title = title;
    }

}

and in Adapter

public class TabsAdapter extends FragmentPagerAdapter{
    private final List<FragmentHolder> mFragmentList = new ArrayList<>();


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

    public void addFrag(FragmentHolder fragmentHolder){
        mFragmentList.add(fragmentHolder);
    }

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

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

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position).title;
    }
}
Lobscouse answered 3/3, 2016 at 21:17 Comment(0)
W
0

@Riptyde4, what i did is just to change the class that is extended by the TabsAdapter from FragmentPagerAdapter to FragmentStatePagerAdapter which allows the different state change in the viewPager to be detected. I did this and it works perfectly.

Wormy answered 14/4, 2017 at 23:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.