Отключить вкладки в TabLayout

Я использовал TabLayout из последней библиотеки поддержки дизайна в своем приложении. Вкладки прикреплены к просмотрщику, который загружает фрагменты для каждой вкладки. Я хочу отключить все вкладки, пока просмотрщик не загрузит фрагмент для выбранной пользователем вкладки. Я не могу отключить вкладку или сделать ее неактивной. Я использовал setEnabled(false) и setClickable(false), но это не работает. Я могу сделать его невидимым с помощью setVisiblity(View.GONE), но я хочу, чтобы вкладки всегда были видны.

    tabLayout = (TabLayout) findViewById(R.id.tabLayout);
    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
    tabLayout.setTabMode(TabLayout.MODE_FIXED);
    tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.near_me_hover).setTag(1));
    tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.all_hostels).setTag(2));
    tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.top_five).setTag(3));
    tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.advanced_search).setTag(4));
    tabLayout.setEnabled(false);
    tabLayout.setClickable(false);

XML

android.support.design.widget.TabLayout
android:id="@+id/tabLayout" android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.15"
android:scrollbars="horizontal"
android:splitMotionEvents="false" >

        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            switch (tab.getPosition()) {
                case 0:
                    viewPager.setCurrentItem(tab.getPosition());
                    tab.setIcon(R.drawable.near_me_hover);
                    break;
                case 1:
                    viewPager.setCurrentItem(tab.getPosition());
                    tab.setIcon(R.drawable.all_hostels_hover);
                    break;
                case 2:
                    viewPager.setCurrentItem(tab.getPosition());
                    tab.setIcon(R.drawable.top_five_hover);
                    break;
                case 3:
                    viewPager.setCurrentItem(tab.getPosition());
                    tab.setIcon(R.drawable.advanced_search_hover);
                    break;
            }
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {
            switch (tab.getPosition()) {
                case 0:
                    tab.setIcon(R.drawable.near_me);
                    break;
                case 1:
                    tab.setIcon(R.drawable.all_hostels);
                    break;
                case 2:
                    tab.setIcon(R.drawable.top_five);
                    break;
                case 3:
                    tab.setIcon(R.drawable.advanced_search);

                    break;
            }

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {
        }
    });
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {
            tabLayout.getTabAt(position).select();
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

person Abhijith Surendran    schedule 09.10.2015    source источник


Ответы (8)


есть 3 метода, реализованные прослушивателем кликов по вкладке, один из них onTabSelected() ставит логическое условие, чтобы проверить, инициализирован ли ваш фрагмент. Затем, если это условие выполнено, разрешите транзакцию. Также инициализируйте вкладки после кода вашего фрагмента

person Mightian    schedule 09.10.2015
comment
@war_hero, как запретить tablayout перенаправлять касание на viewpager? - person alsaleem; 20.10.2018
comment
Вот как бы вы его отключили. val tabStrip = report_tabs.getChildAt(0) as LinearLayout for (i в 0 до tabStrip.childCount) { tabStrip.getChildAt(i).setOnTouchListener { v, event -> true } } - person Minon Weerasinghe; 24.02.2020

Вы можете создать полезную функцию, моя забава в Котлине:

fun disableTabAt(tablayout: TabLayout?, index: Int) {
    (tablayout?.getChildAt(0) as? ViewGroup)?.getChildAt(index)?.isEnabled = false
}

Если вы хотите что-то сделать с представлением, вы можете выполнить отладку или щелкнуть в родительском представлении, чтобы узнать, как оно создано. Таким образом, вы можете делать все, что хотите. В этом случае вы можете перейти к классу Tablayout, чтобы понять.

person Mạnh Hoàng Huynh    schedule 19.12.2018
comment
вам также следует подумать о снижении непрозрачности отключенной вкладки, чтобы она не выглядела так, как будто ее все еще можно выбрать; см. мой ответ - person lasec0203; 27.10.2020

Еще одна хитрость:

Вы можете поместить еще одно пустое прозрачное представление во вкладку, пока ваше требование не будет выполнено. Когда вам нужно включить/отобразить вкладки, просто скройте пустой вид.

person Community    schedule 07.06.2016

Чтобы включить определенную вкладку в position :

LinearLayout tabStrip = ((LinearLayout)tabLayout.getChildAt(0));     
tabStrip.getChildAt(position).setOnTouchListener((v,event)->false);

Чтобы отключить вкладку в position :

 tabStrip.getChildAt(position).setOnTouchListener((v,event)->true);
person Minion    schedule 27.06.2019
comment
Почему? можешь показать код? каково ваше требование? - person Minion; 22.05.2020
comment
Я имею в виду, что он отключает только сенсорное событие, которое пользователь все еще может просматривать, прокручивая пейджер. так что это не идеальный ответ, если пользовательский пейджер прокручивается. - person Deepak Rajput; 22.05.2020
comment
Вы смотрите не на тот вопрос, проверьте этот stackoverflow.com/questions/29442216/ - person Minion; 22.05.2020

Вот 2 вспомогательные функции (kotlin) для отключения и включения TabItem путем передачи его имени.

Протестировано с использованием com.google.android.material:material:1.3.0-alpha02

fun disableTabItemAt(tabLayout: TabLayout?, tabText: String) {
    (tabLayout?.getChildAt(0) as? ViewGroup)?.children?.iterator()?.forEach {
            if((it as TabLayout.TabView).tab?.text == tabText) {
                it.isEnabled = false
                it.alpha = 0.5f
            }
    }
}

fun enableTabItemAt(tabLayout: TabLayout?, tabText: String) {
    (tabLayout?.getChildAt(0) as? ViewGroup)?.children?.iterator()?.forEach {
        if((it as TabLayout.TabView).tab?.text == tabText) {
            it.isEnabled = true
            it.alpha = 1f
        }
    }
}

Итак, если ваши имена вкладок фиксированы, вы можете сделать

disableTabItemAt(tabLayout, "Tab1")

// later enable it

enableTabItemAt(tabLayout, "Tab1")
person lasec0203    schedule 27.10.2020

Если вы хотите отключить вкладку, вам просто нужно использовать customView

Прежде всего, создайте свой собственный макет (например, textView)

v_tabview.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/tabItemView"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:gravity="center"
  android:maxLines="1"
  android:textColor="@drawable/selector_tab" />

создать селектор, для включения/выключения изменения состояния (изменение цвета)

selector_tab.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="#9e9e9e" android:state_enabled="false" /> //gray
  <item android:color="#64b246" android:state_enabled="true" /> //green
</selector>

затем раздуйте его, задайте имена и добавьте в tabLayout

arrayStringNames.forEach { name ->
    val textView: TextView = inflater.inflate(R.layout.v_tabview, tabLayout, false) as TextView
    textView.text = name
    val tab = tabLayout.newTab()
    tab.customView = textView
    tabLayout.addTab(tab)
}

а в конце волшебство! В этом примере кода я отключил все вкладки. Если вам нужно отключить вторую и третью вкладку, проверьте «индекс» в цикле и отключите, если вам нужно

 for (index in 0 until tabLayout.tabCount) {
   ((tabLayout.getTabAt(index)?.customView) as? TextView)?.let { textView ->
     textView.isEnabled = enable //boolean
     (textView.parent as View).enable(enable)
  }
}
person gbixahue    schedule 27.04.2018

Я обнаружил, что лучшим решением является создание дочернего элемента TabLayout, который отключает сенсорное взаимодействие при использовании setEnabled(false). (обратите внимание, что ниже Kotlin)

class NonTouchableTabLayout(context: Context,attributeSet: AttributeSet) : TabLayout(context, attributeSet) {

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        return !isEnabled
    }
}

Таким образом, вы также получаете изменения пользовательского интерфейса, отключая его, и не полагаетесь на внутреннюю работу TabLayout (которая может измениться), как предполагают некоторые другие ответы.

person Matt Smith    schedule 02.11.2020

Если вы хотите отключить одну кнопку вкладки на TabLayout, попробуйте этот код:

tabHost.getTabWidget().getChildTabViewAt(your_index).setEnabled(false);
person Rajan Bhavsar    schedule 09.10.2015
comment
Разве tabhost не отличается от tablayout, который я использовал? - person Abhijith Surendran; 09.10.2015
comment
Вы можете попробовать, если у вас возникнут какие-либо проблемы, дайте мне знать, я проверю это. - person Rajan Bhavsar; 09.10.2015
comment
Я думаю, что tabhost и tablayout из библиотеки поддержки дизайна совершенно разные. Поэтому я не могу использовать этот метод. - person Abhijith Surendran; 09.10.2015
comment
LПозвольте мне проверить это еще раз. - person Rajan Bhavsar; 09.10.2015