RTL

Change ViewPager swipe direction easily

Update 22.03.2016:

Hi again, folks! A few weeks later the code below becomes even more accessible. The library is pushed to jCenter so you just need to add the following dependency to your build.gradle.

dependencies { 
     compile 'com.dision.android:rtlviewpager:1.0.3' 
}

How to use in Java:

        // initialize adapter
        mTabsAdapter = new TabsAdapter(getFragmentManager(), mTabs, true);
        // set adapter to ViewPager
        vp.setAdapter(mTabsAdapter);
        // Set RTL flag
        vp.setRtlOriented(true);
        // set ViewPager to TabLayout
        tl.setupWithViewPager(vp);
        //end

Lately, I’d to implement 2-way swipe direction of a ViewPager. The app requirements were clear: support English and Arabic locale. At first, it didn’t sound scary but then I figured out that there’s an existing official issue.

According to the right-to-left UI paradigm (RTL) a swipe from left to right should scroll page N to page N+1. Currently ViewPager keeps the common LTR swiping direction (a swipe from right to left scrolls page N to page N+1) even if the current locale is an RTL one (Arabic, Hebrew).

Old Solution:

1) Change your TabLayout (or other layout) direction to ltr in xml:

    <android.support.design.widget.TabLayout 
          android:id="@+id/tl_activity_main" 
          android:layout_below="@id/toolbar_activity_main" 
          android:layoutDirection="ltr" 
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" 
          style="@style/DisionTabLayout> 

2) In your Activity/Fragment store user’s language choice in boolean variable. In my case I save it in SharedPreferences and when I need it I get it like this:

        // mArabicLocale is boolean. Constants.ARABIC_LOCALE = "ar"
        mIsArabicLocale = AppPreferences.getLanguageLocale(getActivity()).equals(Constants.ARABIC_LOCALE);

NB: Always check in Fragment when you use method getActivity() if the hosting Activity is alive!

3) Create custom adapter for ViewPager and override methods getItem(int position) and getPageTitle(int position):

    @Override
    public Fragment getItem(int position) {
        if (mIsRtlOrientation && mTabs != null && mTabs.length > 0) {
            return mTabs[mTabs.length - position - 1].getFragment();
        } else {
            return mTabs[position].getFragment();
        }
    }

    @Override
    public int getCount() {
        return mTabs.length;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        if (mIsRtlOrientation && mTabs != null && mTabs.length > 0) {
            return mTabs[mTabs.length - position - 1].getTitle();
        } else {
            return mTabs[position].getTitle();
        }
    }

4) In your Activity/Fragment set the adapter to ViewPager and then apply this ViewPager to TabLayout (if you use TabLayout).

        // initialize adapter
        mTabsAdapter = new TabsAdapter(getSupportFragmentManager(), mTabs, true);
        // set adapter to ViewPager
        vp.setAdapter(mTabsAdapter);
        // set ViewPager to TabLayout
        tl.setupWithViewPager(vp);
        // if RTL orientation, go to last item
        vp.setCurrentItem(vp.getAdapter().getCount() - 1, false);

5) You can check out the full code in Github here

Published by

Stefan Tsekov

Android developer @ Dision