Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 453
tobs Avatar asked Aug 03 '15 08:08

tobs


1 Answers

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

like image 94
Dharmaraj Avatar answered Oct 16 '22 01:10

Dharmaraj