How can I disable click on TabLayout in Android-ThrowExceptions

Exception or error:

I want use TabLayout in my application for use fragment and ViewPager.
but I want disable click on TabLayout to switch between fragment, just swipe to switch between fragmenst.
I write below codes, but not work me and when click on TabLayout items, go to that fragment!

MainActivity XML :

<android.support.design.widget.CoordinatorLayout 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.design.widget.AppBarLayout
            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">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:gravity="center"
                    android:text="@string/app_namefull"
                    android:textSize="23sp" />

            </android.support.v7.widget.Toolbar>

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="72dp"
                app:tabGravity="fill"
                app:tabIndicatorColor="@color/white"
                app:tabMode="fixed" />
        </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>

MainActivity java:

public class Main_Page extends AppCompatActivity {

    private CollapsingToolbarLayout mCollapsingToolbarLayout;
    private Toolbar toolbar;
    private TabLayout tabLayout;
    private ViewPager viewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main__page);

        mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
        //mCollapsingToolbarLayout.setTitle(getResources().getString(R.string.app_name));

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        //getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        viewPager = (ViewPager) findViewById(R.id.viewpager);
        setupViewPager(viewPager);

        tabLayout = (TabLayout) findViewById(R.id.tabs);
        LinearLayout tabStrip = ((LinearLayout)tabLayout.getChildAt(0));
        for(int i = 0; i < tabStrip.getChildCount(); i++) {
            tabStrip.getChildAt(i).setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    return true;
                }
            });
        }
        tabLayout.setupWithViewPager(viewPager);
        setupTabIcons();
    }

    /**
     * Adding custom view to tab
     */
    private void setupTabIcons() {

        TextView tabOne = (TextView) LayoutInflater.from(this).inflate(R.layout.custom_tab, null);
        tabOne.setText(R.string.free_fragment_title);
        tabOne.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_download_image, 0, 0);
        tabLayout.getTabAt(0).setCustomView(tabOne);

        TextView tabTwo = (TextView) LayoutInflater.from(this).inflate(R.layout.custom_tab, null);
        tabTwo.setText(R.string.paid_fragment_title);
        tabTwo.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_paid_download_image, 0, 0);
        tabLayout.getTabAt(1).setCustomView(tabTwo);

        TextView tabThree = (TextView) LayoutInflater.from(this).inflate(R.layout.custom_tab, null);
        tabThree.setText(R.string.pdf_fragment_title);
        tabThree.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_pdf_icon, 0, 0);
        tabLayout.getTabAt(2).setCustomView(tabThree);
    }

    /**
     * Adding fragments to ViewPager
     * @param viewPager
     */
    private void setupViewPager(ViewPager viewPager) {
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
        adapter.addFrag(new free_fragment(), "رایگان ها");
        adapter.addFrag(new paid_fragment(), "پرداختی ها");
        adapter.addFrag(new pdf_fragment(), "مقالات");
        viewPager.setAdapter(adapter);
    }

    class ViewPagerAdapter extends FragmentPagerAdapter {
        private final List<Fragment> mFragmentList = new ArrayList<>();
        private final List<String> mFragmentTitleList = new ArrayList<>();

        public ViewPagerAdapter(FragmentManager manager) {
            super(manager);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }

        @Override
        public int getCount() {
            return mFragmentList.size();
        }

        public void addFrag(Fragment fragment, String title) {
            mFragmentList.add(fragment);
            mFragmentTitleList.add(title);
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentTitleList.get(position);
        }
    }
}

for disable click on TabLayout I use this code:

LinearLayout tabStrip = ((LinearLayout)tabLayout.getChildAt(0));
for(int i = 0; i < tabStrip.getChildCount(); i++) {
    tabStrip.getChildAt(i).setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return true;
        }
    });
}

How can I solve this problem? Thanks all <3

How to solve:

You are accessing tabs before setupWithViewPager, thats why your code is not working. So first set tabs then settouchlistener code.

Try this:

tabLayout.setupWithViewPager(viewPager);
    setupTabIcons();

LinearLayout tabStrip = ((LinearLayout)mTabLayout.getChildAt(0));
    for(int i = 0; i < tabStrip.getChildCount(); i++) {
        tabStrip.getChildAt(i).setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return true;
            }
        });
    }

###

tabLayout.clearOnTabSelectedListeners();

###

touchable array list will solve this issue.

declare the activity

var touchableList: ArrayList<View>? = ArrayList()

disable all tab

touchableList = tabLayout?.touchables
touchableList?.forEach { it.isEnabled = false }

Enable the tab

touchableList?.get(0)?.isEnabled = true

###

No need to use a Linear Layout, you could just add this on the activity:

private void setUntouchableTab () {
    tablayout.setupWithViewPager(viewpager, true);
    tablayout.clearOnTabSelectedListeners();
    for (View v : tablayout.getTouchables()) {
        v.setEnabled(false);
    }
}

###

This is what worked for me:

class LockableTabLayout : TabLayout {

    var swipeable: Boolean = true

    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean = !swipeable
}

###

For ViewPager2 (minimum v1.1.0) you can accomplish this in the TabLayoutMediator.

new TabLayoutMediator(tabLayout, pager,
        (tab, position) -> {
            tab.view.setClickable(false);
        }
).attach();

And in build.gradle:

com.google.android.material:material:1.1.0-rc02

###

The above answer here, disabled the tab item click when you already finish populated your tab item or already defined the tabitem on xmls.

e.g:

        <android.support.design.widget.TabLayout
            android:id="@+id/tabla_quiz_navigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.design.widget.TabItem
                android:layout_width="wrap_content"
                android:text="1"
                android:layout_height="wrap_content"/>

            <android.support.design.widget.TabItem
                android:layout_width="wrap_content"
                android:text="2"
                android:layout_height="wrap_content"/>

            <android.support.design.widget.TabItem
                android:layout_width="wrap_content"
                android:text="3"
                android:layout_height="wrap_content"/>

        </android.support.design.widget.TabLayout>

But, if you’ve different cases, when using Observable data or dynamic tabitem. e.g:

        // QuizFragment.kt
        quizListLive.observe(this@QuizFragment, Observer { quizList ->

            quizList?.takeIf { list -> list.isNotEmpty() }?.let {

                // this is where new fragment added
                it.forEachIndexed { j, quiz ->
                    mViewPagerAdapter?.addFragment(
                            fragment = QuizFragmentSub.newInstance(quiz = quiz),
                            title = (j + 1).toString()
                    )
                }

                // notify the viewpager, I'm using kotlin extension to call widget id
                vp_quiz_content.adapter?.notifyDataSetChanged()

                // then, childCount will have size > 0
                // disable tablayout click
                val tabStrip = tabla_quiz_navigation.getChildAt(0) as LinearLayout
                for (i in 0 until tabStrip.childCount) {
                    tabStrip.getChildAt(i).setOnTouchListener { _, _ -> true }
                }
            }
        })

====

        // quiz_fragment.xml
        <android.support.design.widget.TabLayout
            android:id="@+id/tabla_quiz_navigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"></android.support.design.widget.TabLayout>

the method has slightly different on the time of its invocation, you just have to setup your tabitem to disable its click after all viewpager fragment already added.

if there’s someone have better approach to this, please edit my answer

Leave a Reply

Your email address will not be published. Required fields are marked *