8

I have a fragmentPagerAdapter with 3 fragments in it. How would I disable the swiping between the 3 fragments so the user only uses the tabview to go between fragments?

private class ViewPagerAdapter extends FragmentPagerAdapter
{
    ArrayList<Fragment> fragments = new ArrayList<>();
    ArrayList<String> tabTitles = new ArrayList<>();

    public ViewPagerAdapter(android.support.v4.app.FragmentManager fragmentManager)
    {
        super(fragmentManager);
    }
    @Override
    public Fragment getItem(int position)
    {
        return fragments.get(position);
    }
    @Override
    public int getCount()
    {
        return fragments.size();
    }
    @Override
    public CharSequence getPageTitle(int position)
    {
        return tabTitles.get(position);
    }
    public void addFragments(Fragment fragment, String titles)
    {
        this.fragments.add(fragment);
        this.tabTitles.add(titles);
    }
}
peterh
  • 11,875
  • 18
  • 85
  • 108
TheQ
  • 1,949
  • 10
  • 38
  • 63
  • Use buttons instead of viewpager tab and view pager – Noorul Jan 15 '17 at 01:33
  • 1
    why use buttons? tab layout and view pager were meant for multiple fragments – TheQ Jan 15 '17 at 01:38
  • I think the adapter will have no 'say' in this, it just provides the ViewPager with data. If you want to prevent the siwping, the ViewPager will be 'responsible' http://stackoverflow.com/questions/9650265/how-do-disable-paging-by-swiping-with-finger-in-viewpager-but-still-be-able-to-s – fweigl Jan 15 '17 at 01:45
  • 1
    @Ascorbin but im extending from FragmentPagerAdapter not ViewPager – TheQ Jan 15 '17 at 01:58

2 Answers2

8

You can setup a custom view pager like this :-

public class LockableViewPager extends ViewPager {
    private boolean swipeable;

    public LockableViewPager(Context context) {
        super(context);    
    }    

    public LockableViewPager(Context context, AttributeSet attrs) {    
        super(context, attrs);    
        this.swipeable = true;    
    }

    @Override    
    public boolean onTouchEvent(MotionEvent event) {    
        if (this.swipeable) {    
            return super.onTouchEvent(event);    
        }    
        return false;    
    }

    @Override

    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (this.swipeable) {
            return super.onInterceptTouchEvent(event);
        }
        return false;
    }

    public void setSwipeable(boolean swipeable) {
        this.swipeable = swipeable;
    }
}

And then in the layout you can set it as :-

<mypackage.lockableviewpager 
    android:id="@+id/photosViewPager" 
    android:layout_height="match_parent"
    android:layout_width="match_parent"/>

And then just call

setSwipeable(false)

Hope it helps.

ZooMagic
  • 616
  • 7
  • 15
Abhriya Roy
  • 1,338
  • 17
  • 23
  • so i cannot use FragmentPagerAdapter to accomplish this? – TheQ Jan 15 '17 at 02:00
  • I don't think that you can do it using fragmentpager adapter. As far as I know, the only way is by defining a custom view pager. :) – Abhriya Roy Jan 15 '17 at 02:02
  • 1
    So how would i set the tab titles and do getItem and getCount in this custom viewpager? Beacuse in the fragmentPagerAdapter i have getItem,getCount, and getPageTitle – TheQ Jan 15 '17 at 02:06
  • oh im stupid i was mixing the view pager and the adapter! thanks for the solution! – TheQ Jan 15 '17 at 02:08
  • 1
    Please refer to this link https://guides.codepath.com/android/ViewPager-with-FragmentPagerAdapter it provides in depth instructions and code snaps as well. – Abhriya Roy Jan 15 '17 at 02:08
  • yeah, im going to implement this right now and then mark it as solved once it works. Give me a min or two :) – TheQ Jan 15 '17 at 02:11
  • so i implemented the code, but my app keeps crashing, because it cannot inflate the layout because it cannot find my custom view pager. Have you had this problem? – TheQ Jan 15 '17 at 02:33
  • No didn't occur to me. Did you check if you have written it correctly in the layout? Did you mention your package name properly at the place of 'mypackage'? – Abhriya Roy Jan 15 '17 at 02:35
  • I marked your answer as correct, because i know its a correct solution. But i cannot get the android to match the xml ViewPager to the custom one i made :/ it just cant find it. – TheQ Jan 15 '17 at 02:52
  • im getting this exception `Caused by: java.lang.ClassNotFoundException: Didn't find class "com.daprlabs.aaron.zivitApp.Main.Main.MyViewPager" on path: DexPathList[[zip file "/data/app/com.daprlabs.aaron.swipedeck2-1/base.apk"],nativeLibraryDirectories=[/data/app/com.daprlabs.aaron.swipedeck2-1/lib/arm64, /data/app/com.daprlabs.aaron.swipedeck2-1/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]` – TheQ Jan 15 '17 at 02:58
  • Thanks for marking it as correct. The link I have posted in these comments is the place where I myself obtained the solution from when I was having this issue. So please check that out it and follow the instructions carefully. They are really good. I think you won't get the error anymore after you've referred the link. – Abhriya Roy Jan 15 '17 at 03:26
  • I figured it out. So, i have to put ViewPager in a seperate class in order for the xml layout to find it :) – TheQ Jan 15 '17 at 03:33
  • Yes. For any custom view, you have to make a separate class where you have to define it. – Abhriya Roy Jan 15 '17 at 03:49
7

Here's a little more elaboration on the LockableViewPager class example...

First instead of marking up a ViewPager like this

<android.support.v4.view.ViewPager
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</android.support.v4.view.ViewPager>

you want to make a custom class that inherits VP like this

public class LockableViewPager extends ViewPager {
  private boolean swipeable;

  public LockableViewPager(Context context) {
      super(context);
  }

  public LockableViewPager(Context context, AttributeSet attrs) {
      super(context, attrs);
      this.swipeable = true;
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
      if (this.swipeable) {
          return super.onTouchEvent(event);
      }
      return false;
  }

  @Override
  public boolean onInterceptTouchEvent(MotionEvent event) {
      if (this.swipeable) {
          return super.onInterceptTouchEvent(event);
      }
      return false;
  }

  public void setSwipeable(boolean swipeable) {
      this.swipeable = swipeable;
  }
}

Pay attention to this method

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
  if (this.swipeable) {
      return super.onInterceptTouchEvent(event);
  }
  return false;
}

then you can mark up your custom class that already acts as ViewPager plus intercepts touch events

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

In your activity's java class that contains LockableViewPager set

LockableViewPager viewPager;
OnCreate() {
  viewPager = (LockableVewPager) findViewById(R.id.*id of pager*);
  viewPager.setSwipable(false);
}

Extendng the class you want (i.e. ViewPager) is the CORRECT way to do this unless you are making a totally different class that doesn't behave the same way ;* good luck

Rebel Rae
  • 79
  • 3
  • 2
    Question was about the FragmentPagerAdapter, there are plenty of answer for a Viewpager on stackoverflow – Alberto M May 25 '18 at 10:08