tobs
tobs

Reputation: 719

ViewPager swipe doesn't work with RecyclerView

I want to implement a simple swipe navigation using a ViewPager with fragments that hold and manage a RecyclerView.

The Fragments are created and can be switched using setCurrentItem(), but you cannot swipe left or right to switch pages. The ViewPager seems to ignore any swipe gesture.

My Activity layout:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"

    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"
        android:layout_marginTop="?attr/actionBarSize"/>

    <android.support.v7.widget.Toolbar
                  ...                 />

</FrameLayout>

I populate the ViewPager using a FragmentPagerAdapter in my onCreate() like so:

viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.addOnPageChangeListener(this);
viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
       @Override
       public Fragment getItem(int position) {
           switch (position) {
               case 0:
                   return new Dummy2Fragment();

               case 1:
                   return new Dummy2Fragment();

               default:
                   return null;
           }
        }

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

       @Override
       public CharSequence getPageTitle(int position) {
           return "Dataset " + (position + 1);
       }
   });

The fragment layout is a simple FrameLayout which wraps a RecyclerView:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/background_material_light"/>

</FrameLayout>

The adapter and the layout manager are set in the fragment's onCreateView:

recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 6, LinearLayoutManager.VERTICAL, false));

Edit #1

I think I did not ask my question clear enough.
I have a working Pager with a working TabLayout that is populated by a 'FragmentPagerAdapter', meaning that Fragments are properly created and the tab layout displays a clickable tab for each item. Every Fragment in this ViewPager displays a RecyclerView with a GridLayoutManager.

However, the ViewPager doesn't seem to receive any swipe gesture, You can change the current selected position via the TabLayout, but not by swiping for example from left to right.
It looks like the RecyclerView consumes all swipe events regardless of the layout direction, which is set to vertical.

Any ideas?

Upvotes: 10

Views: 7983

Answers (1)

Dharmaraj
Dharmaraj

Reputation: 1306

You can use tablayout with Viewpager like this

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

<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/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"

    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"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

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

        />

</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.CoordinatorLayout>

Also set

   tabLayout = (TabLayout) rv.findViewById(R.id.tabs);
   tabLayout.setupWithViewPager(viewPager);

and Method setupWithViewPager is like

  private void setupViewPager(ViewPager viewPager) {
      adapter = new Adapter(getChildFragmentManager());
      adapter.addFragment(new MatesListFragment(), "Mates");
      adapter.addFragment(new FavoursListFragment(), "Favours");
      adapter.addFragment(new FavemeListFragment(), "FavMe");
        viewPager.setAdapter(adapter);
}


 class Adapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragments = new ArrayList();
    private final List<String> mFragmentTitles = new ArrayList();

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

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

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

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

     public int getItemPosition(Object object) {
         return POSITION_NONE;
     }
    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitles.get(position);
    }
}

In MatesListFragment, FavoursListFragment etc. you have your RecyclerView layout

Upvotes: 2

Related Questions