Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to put Vertically swiped ViewPager in a Horizontally swiped ViewPager

I'm customizing my Android app to swipe in the four directions, I'm using ViewPager to swipe Horizontally and VerticalViewPager to swipe vertically (this is like a modification of DirectionalViewPager as the original one is deprecated) . the problem is When containing the ViewPager in the VerticalViewPager, the Vertical swiping works only and when containing VerticalViewPager in the ViewPager the Horizontal swipe works only, this is my code for the first state:

VerticalViewPager verticalViewPager = (VerticalViewPager) findViewById(R.id.vertical_pager);
        verticalViewPager.setAdapter(new TabPagerAdapter(getSupportFragmentManager()));
        verticalViewPager.setPageTransformer(true, new ViewPager.PageTransformer() {
            @Override
            public void transformPage(View view, float position) {
                int pageWidth = view.getWidth();
                int pageHeight = view.getHeight();

                if (position < -1) { // [-Infinity,-1)
                    // This page is way off-screen to the left.
                    view.setAlpha(0);

                } else if (position <= 1) { // [-1,1]
                    // Modify the default slide transition to shrink the page as well
                    float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
                    float vertMargin = pageHeight * (1 - scaleFactor) / 2;
                    float horzMargin = pageWidth * (1 - scaleFactor) / 2;
                    if (position < 0) {
                        view.setTranslationY(vertMargin - horzMargin / 2);
                    } else {
                        view.setTranslationY(-vertMargin + horzMargin / 2);
                    }

                    // Scale the page down (between MIN_SCALE and 1)
                    view.setScaleX(scaleFactor);
                    view.setScaleY(scaleFactor);

                    // Fade the page relative to its size.
                    view.setAlpha(MIN_ALPHA +
                            (scaleFactor - MIN_SCALE) /
                                    (1 - MIN_SCALE) * (1 - MIN_ALPHA));

                } else { // (1,+Infinity]
                    // This page is way off-screen to the right.
                    view.setAlpha(0);
                }
            }
        });

        verticalViewPager.setCurrentItem(1);

        TabPagerAdapter TabAdapter = new TabPagerAdapter(getSupportFragmentManager());
        ViewPager Tab = (ViewPager) findViewById(R.id.pager);
        Tab.setAdapter(TabAdapter);
        Tab.setCurrentItem(1);

The TabPagerAdapter class:

public class TabPagerAdapter extends FragmentStatePagerAdapter {
    public TabPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        switch (i) {
        case 0:
            //Fragment for Left side
            return new AC_Left();
        case 1:
           //Fragment for Center side
            return new AC_Center();
        case 2:
            //Fragment for Right side
            return new AC_Right();
        }
        return null;

    }

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

AC_Left, AC_Right, and AC_Center are similar fragments except of the layout returned:

public class AC_Center extends Fragment {
  @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
              Bundle savedInstanceState) {
          View ac_center_frag = inflater.inflate(R.layout.ac_center_fragment, container, false);
          return ac_center_frag;

  }
}

And the XML file:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg" >

  <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@+id/buttonBar"
            android:orientation="vertical"
            android:weightSum="1" >

  <com.example.myapp.VerticalViewPager
            android:id="@+id/vertical_pager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" >

            <android.support.v4.view.ViewPager
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/pager"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

  </com.example.myapp.VerticalViewPager>

 </LinearLayout>
</RelativeLayout>
like image 621
Muhammed Refaat Avatar asked Apr 17 '14 10:04

Muhammed Refaat


People also ask

What is the difference between ViewPager and ViewPager 2?

ViewPager2 is an improved version of the ViewPager library that offers enhanced functionality and addresses common difficulties with using ViewPager . If your app already uses ViewPager , read this page to learn more about migrating to ViewPager2 .

Can you put a ViewPager in a fragment?

Steps for implementing viewpager: Adding the ViewPager widget to the XML layout (usually the main_layout). Creating an Adapter by extending the FragmentPagerAdapter or FragmentStatePagerAdapter class.

Can I use ViewPager with views not with fragments?

In ViewPager2 you do not need to use Fragments at all. Just create an Adapter as you would a RecyclerView Adapter. and set it to ViewPager2. One thing to keep in mind however is layout height of the view you want to inflate should be match_parent and not wrap_content as you would for a recyclerView.

How many methods does the PageTransformer of a ViewPager expose?

PageTransformer interface and supply it to the ViewPager2 object. The interface exposes a single method, transformPage() . At each point in the screen's transition, this method is called once for each visible page (generally there's only one visible page) and for adjacent pages just off the screen.


1 Answers

I created a library for this with a sample application and put it on github. Basically it maintains a view port and updates the view pager on each page change. There's an adapter you have to implement to give it fragments for each row, column index. It's admittedly a little hacked together, but should work in the mean time. There's a bit mask you can set to have it wrap in whatever directions you need. Set it to GRID_WRAP_NONE to have it not wrap at all.

https://github.com/btate/BTGridPager-Android

This might not be exactly what you need but it should get you started.

like image 153
codeetcetera Avatar answered Sep 28 '22 14:09

codeetcetera