1

I am not that experienced in Java so I can't figure it out myself. I bought a template with a tablayout which looks like this (image 1):

This is how my Template looks like

I want to disable the swipe function between these two tabs, so it should only be possible to get to "TAB 2" by clicking on the tab "TAB 2".

There are a lot of tutorials in the Internet but non of them fits to my code so I'm a bit confused.

Here is my TabFragment:

public class TabFragment extends Fragment {
public static TabLayout tabLayout;
public static ViewPager viewPager;
public static int int_items = 2 ;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {


    View x =  inflater.inflate(R.layout.tab_layout,null);
    tabLayout = (TabLayout) x.findViewById(R.id.tabs);
    viewPager = (ViewPager) x.findViewById(R.id.viewpager);

    viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));

    viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        public void onPageScrollStateChanged(int state) {}
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}



    tabLayout.post(new Runnable() {
        @Override
        public void run() {
            tabLayout.setupWithViewPager(viewPager);
        }
    });

    return x;

}

class MyAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int position)
    {

        if(position == 0){
            return new Tab1();
        }
        if(position == 1){
            return new Tab2();
        }



        return null;
    }

    @Override
    public int getCount() {

        return int_items;

    }


    @Override
    public CharSequence getPageTitle(int position) {

        switch (position){
            case 0 :
                return "Tab 1";
            case 1 :
                return "Tab 2";

        }
        return null;
    }
}}

and my tab_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="wrap_content">


    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        app:tabGravity="fill"
        app:tabMode="fixed"
        android:background="@color/material_blue_grey_800"
        app:tabIndicatorColor="@color/orange"
        app:tabSelectedTextColor="@color/orange"
        app:tabTextColor="@color/white"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </android.support.design.widget.TabLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="50dp">

    </android.support.v4.view.ViewPager>



</LinearLayout>

I tried my best to figure out how to solve it but didn't succeed, so I hope one of you can help me with this small problem :)

Thanks a lot.

Fisch Gesicht
  • 81
  • 1
  • 9
  • 1
    Possible duplicate of [How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically?](https://stackoverflow.com/questions/9650265/how-do-disable-paging-by-swiping-with-finger-in-viewpager-but-still-be-able-to-s) – Vedprakash Wagh Jun 28 '19 at 15:27
  • You can checkout this link: https://stackoverflow.com/questions/9650265/how-do-disable-paging-by-swiping-with-finger-in-viewpager-but-still-be-able-to-s – Richmahnn Jun 28 '19 at 15:28
  • @VedprakashWagh no, thats what I was talking about, there are a lot of answers on how to solve this problem but non of them fits to my code. – Fisch Gesicht Jun 28 '19 at 15:28
  • It's the exact same thing. That question also wants to do the exact same thing, selecting only when clicked on those buttons. Check it out once. – Vedprakash Wagh Jun 28 '19 at 15:29

2 Answers2

4

You need to create a custom ViewPager that intercepts the onTouch events and avoid the default behaviour. This way the user wont be able to swipe between pages but will be able to touch on the tabs.

You can check this link where is already answered: How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically?

EDIT

I'll explain it by steps:

  1. Create a new class called NonSwipeableViewPager
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.Scroller;
import java.lang.reflect.Field;

public class NonSwipeableViewPager extends ViewPager {

    public NonSwipeableViewPager(Context context) {
        super(context);
        setMyScroller();
    }

    public NonSwipeableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        setMyScroller();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages
        return false;
    }

    //down one is added for smooth scrolling

    private void setMyScroller() {
        try {
            Class<?> viewpager = ViewPager.class;
            Field scroller = viewpager.getDeclaredField("mScroller");
            scroller.setAccessible(true);
            scroller.set(this, new MyScroller(getContext()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public class MyScroller extends Scroller {
        public MyScroller(Context context) {
            super(context, new DecelerateInterpolator());
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/);
        }
    }
}
  1. Modify your layout to use the new ViewPager
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="wrap_content">


    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        app:tabGravity="fill"
        app:tabMode="fixed"
        android:background="@color/material_blue_grey_800"
        app:tabIndicatorColor="@color/orange"
        app:tabSelectedTextColor="@color/orange"
        app:tabTextColor="@color/white"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </android.support.design.widget.TabLayout>

    <NonSwipeableViewPager <!-- You will need to import this correctly with your class package -->
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="50dp">

    </NonSwipeableViewPager>



</LinearLayout>
  1. Update your activity with the new ViewPager
public class TabFragment extends Fragment {
public static TabLayout tabLayout;
public static NonSwipeableViewPager viewPager; // This line changed
public static int int_items = 2 ;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {


    View x =  inflater.inflate(R.layout.tab_layout,null);
    tabLayout = (TabLayout) x.findViewById(R.id.tabs);
    viewPager = (NonSwipeableViewPager) x.findViewById(R.id.viewpager); // This line changed

    viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));

    viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        public void onPageScrollStateChanged(int state) {}
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}



    tabLayout.post(new Runnable() {
        @Override
        public void run() {
            tabLayout.setupWithViewPager(viewPager);
        }
    });

    return x;

}

You can keep the same adapter MyAdapter.

This will avoid the swipe between tabs but will keep the click on each one.

Jaime Suarez
  • 660
  • 4
  • 11
  • Why write link only answer? Same answer is available at that link, so instead of marking it as duplicate, why write an answer? – Vedprakash Wagh Jun 28 '19 at 15:28
  • Yes I saw this answer already but my code looks different so I don't know what to do exactly – Fisch Gesicht Jun 28 '19 at 15:29
  • @FischGesicht You need to create a custom NonSwipeableViewPager class as mentioned in that answer, and the instead of using android.support.v4.view.ViewPager in your XML layout, you should use NonSwipeableViewPager as mentioned in that answer. – Vedprakash Wagh Jun 28 '19 at 15:31
0

I know this is quite old but you need to switch to ViewPager2.

ViewPager2 replaces androidx.viewpager.widget.ViewPager, addressing most of its predecessor’s pain-points, including right-to-left layout support, vertical orientation, modifiable Fragment collections, etc.

If you need to disable user swipe support then you can call:

viewPager2.isUserInputEnabled = false
Giddy Naya
  • 4,237
  • 2
  • 17
  • 30