Tab selector not working on previous tab click when swipe on viewpager
Asked Answered
M

6

10

I'm following this example..

I'm having one issue, when I swipe on ViewPager respective fragment appear but when I swipe from from left to right or right to left and select previous Tab the Tab indicator appear on new selected Tab but respective fragment not appear on ViewPager. Please help me, where I'm getting wrong?

Monitory answered 22/7, 2015 at 5:32 Comment(7)
add some images to clarify your question e.g how it looks before and afterMiru
I'm having this same problem. I have 4 tabs in a TabLayout, setup with a ViewPager. Let's say I'm on tab 0. If I swipe right, I go to tab 1. If I swipe left I go back to tab 0. Everything works, tab layout switches, viewpager shows the correct fragment. The problem is here: I'm on tab 0. If I SWIPE to tab 1, it works, but if I then CLICK tab 0, the tab layout "tabIndicator" will go to tab 0, but the viewpager will not change the fragment, and tab 1 title will stay highlighted. It's fixed immediately by clicking or swiping away.Coxa
FYI i'm using TabLayout and ViewPager with setupWithViewPager() methodCoxa
Which AppCompat lib version are you guys using? New widgets are notoriously buggy in this lib, so I recommend first trying this scenario out with the newest one (currently 23.0.0) in case you haven't checked that yet.Gati
Yeah it was a bug in the widget: code.google.com/p/android/issues/detail?id=183123Coxa
use track the fragment and use a direct call on tablayout to select itTridentum
update your support library to 23.0.1 .. bug is solved ... Read this section Changes for Design Support library in developer.android.com/tools/support-library/index.htmlGrannias
G
5

It was bug in support lib 23.0.0 but it is solved in 23.0.1. First of all update your suppory library using SDK manager from the extras section. and write the following line in app gradle file.

compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:design:23.0.1'

for your reference

https://developer.android.com/topic/libraries/support-library/revisions.html and read the Changes for Design Support library in Android Support Library, revision 23.0.1 section

Grannias answered 5/9, 2015 at 11:52 Comment(3)
Thanks Man, you solved my issue on which I spent my 1 day :)Raspberry
@Grannias I am Facing the Same Issue. I am using support library 24.0.0 and also tried the support library 24.1.1Phony
This issue is not fixed as of mid 2016Triforium
K
4

This is what i use and works fine.

Adapter:

    public class SCFragmentPagerAdapter extends FragmentPagerAdapter {

    private final List<Fragment> mFragments = new ArrayList<>();
    private final List<String> mFragmentTitles = new ArrayList<>();

    private Context mContext;
    private FragmentManager mFragmentManager;

    public SCFragmentPagerAdapter(FragmentManager fm, Context context) {
        super(fm);
        this.mFragmentManager = fm;
        this.mContext = context;
    }

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

    // Return the correct Fragment based on index
    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position);
    }

    public void addFragment(Fragment fragment, String title) {
        mFragments.add(fragment);
        mFragmentTitles.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        // Return the tab title to SlidingTabLayout
        return mFragmentTitles.get(position);
    }


    public Fragment getActiveFragment(ViewPager container, int position) {
        String name = makeFragmentName(container.getId(), position);
        return  mFragmentManager.findFragmentByTag(name);
    }

    private static String makeFragmentName(int viewId, int index) {
        return "android:switcher:" + viewId + ":" + index;
    }

}

Activity:

public class SCWelcomeActivity extends AppCompatActivity implements
        SCWelcomeFragment.OnFragmentInteractionListener,
        SCSyncFragment.OnFragmentInteractionListener,
        SCRegisterFragment.OnFragmentInteractionListener,
        SCConfirmationFragment.OnFragmentInteractionListener {

    private static final String TAG = SCWelcomeActivity.class.getSimpleName();

    private ViewPager viewPager = null;
    private TabLayout tabLayout = null;
    private Toolbar toolbar = null;
    private SCFragmentPagerAdapter adapter = null;

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

        // Layout manager that allows the user to flip through the pages
        viewPager = (ViewPager) findViewById(R.id.viewpager);
        setupViewPager(viewPager);

        // Initialize the Sliding Tab Layout
        tabLayout = (TabLayout) findViewById(R.id.tablayout);

        // Connect the viewPager with the sliding tab layout
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onFragmentInteraction(Uri uri) {

    }


    private void setupViewPager(ViewPager viewPager) {

        adapter = new SCFragmentPagerAdapter(getSupportFragmentManager(), SCWelcomeActivity.this);
        adapter.addFragment(SCWelcomeFragment.newInstance(), getString(R.string.title_tab1));
        adapter.addFragment(SCSyncFragment.newInstance(), getString(R.string.title_tab2));
        adapter.addFragment(SCRegisterFragment.newInstance(), getString(R.string.title_tab3));
        adapter.addFragment(SCConfirmationFragment.newInstance(), getString(R.string.title_tab4));


        viewPager.setAdapter(adapter);
        viewPager.setOffscreenPageLimit(4);
    }

    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        public void onFragmentInteraction(Uri uri);
    }
}

Fragment Example :

    public class SCWelcomeFragment extends Fragment {

    private OnFragmentInteractionListener mListener;

    public static SCWelcomeFragment newInstance() {
        SCWelcomeFragment fragment = new SCWelcomeFragment();
        return fragment;
    }

    public SCWelcomeFragment() {
        super();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_scwelcome, container, false);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        public void onFragmentInteraction(Uri uri);
    }
}

Layout:

    <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/coordinator"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <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.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="130dp"
        android:fitsSystemWindows="true"
        android:gravity="bottom"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin"
            android:layout_gravity="center"
            android:theme="@style/ThemeOverlay.AppCompat.Dark"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tablayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />


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


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

Please try to implement the adapter as i do. Pay close attention that in mine Adapter all instances are saved in the

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

In your case you are always returning a new instance. So that's why a set the setOffscreenPageLimit(4). to 4 so they are kept in memory as well.

Kktp answered 1/9, 2015 at 1:59 Comment(0)
D
4

In your activity, after find Views by Id, you should "config" your ViewPager and TabLayout. Some necessary features maybe: "addOnPageChangeListener" for ViewPager and "setOnTabSelectedListener" for your TabLayout like this:

public class MainActivity extends AppCompatActivity {

private final int numOfPages = 4; //viewpager has 4 pages
private final String[] pageTitle = {"Food", "Movie", "Shopping", "Travel"};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);

    for (int i = 0; i < numOfPages; i++) {
        tabLayout.addTab(tabLayout.newTab().setText(pageTitle[i]));
    }

    //set gravity for tab bar
    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

    final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
    final PagerAdapter adapter = new PagerAdapter
            (getSupportFragmentManager(), numOfPages);

    viewPager.setAdapter(adapter);
    viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    tabLayout.setOnTabSelectedListener(onTabSelectedListener(viewPager));
}

private TabLayout.OnTabSelectedListener onTabSelectedListener(final ViewPager pager) {
    return new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            pager.setCurrentItem(tab.getPosition());
        }

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

        }

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

        }
    };
}

I have a tutorial post about this and it works well! There is no error like yours. Hope it help: http://www.devexchanges.info/2015/08/android-material-design-viewpager-with.html

Dudek answered 7/9, 2015 at 2:29 Comment(1)
Awesome tutorial. It makes sense. Thanks for the answer. This should be the upvoted answerConcentre
T
2

None of the above answers worked for me AS of end of 2016 the bug still exists in design support library 24+. I was able to fix this issue by wrapping the tab layout inside a
co-ordinator layout

Triforium answered 6/10, 2016 at 8:34 Comment(1)
spent hrs.. this fixed the issue.. and yes support library 24+ issue still exists..Jehial
W
0

I have more shorter variant to fix this bug (android support design lib v.23.0.0):

...
//initialize views
    mViewPager.setAdapter(pagerAdapter);
    mTabLayout.setupWithViewPager(mViewPager);
    mViewPager.clearOnPageChangeListeners();
    mViewPager.addOnPageChangeListener(new WorkaroundTabLayoutOnPageChangeListener(mTabLayout));
...

And class WorkaroundTabLayoutOnPageChangeListener:

public class WorkaroundTabLayoutOnPageChangeListener extends TabLayout.TabLayoutOnPageChangeListener {
    private final WeakReference<TabLayout> mTabLayoutRef;

    public WorkaroundTabLayoutOnPageChangeListener(TabLayout tabLayout) {
        super(tabLayout);
        this.mTabLayoutRef = new WeakReference<>(tabLayout);
    }

    @Override
    public void onPageSelected(int position) {
        super.onPageSelected(position);
        final TabLayout tabLayout = mTabLayoutRef.get();
        if (tabLayout != null) {
            final TabLayout.Tab tab = tabLayout.getTabAt(position);
            if (tab != null) {
                tab.select();
            }
        }
    }
}
Wallaby answered 3/9, 2015 at 18:17 Comment(0)
R
0

Are you using support library version 23.0.0. There was an issue https://code.google.com/p/android/issues/detail?id=183123 which looks similar to yours. If that is the case indeed, update your support library version to 23.0.1. This issue has been fixed.

Raquelraquela answered 7/9, 2015 at 22:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.