【问题标题】:Disable Tabs in TabLayout [duplicate]禁用 TabLayout 中的选项卡 [重复]
【发布时间】:2015-10-09 04:05:42
【问题描述】:

我在我的应用程序中使用了来自最新设计支持库的TabLayout。这些选项卡附加到一个视图页面,它为每个选项卡加载片段。我想禁用所有选项卡,直到 viewpager 加载用户选择的选项卡的片段。我无法禁用选项卡布局或使其不可点击。我使用过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="水平"
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) {

        }
    });

【问题讨论】:

    标签: android android-fragments tabs androiddesignsupport android-tablayout


    【解决方案1】:

    你可以创建一个 util 函数,我在 Kotlin 中的乐趣:

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

    当您想对视图做某事时,您可以调试或单击父视图以了解它是如何创建的。通过这种方式,你可以做任何你想做的事情。对于这种情况,你可以去 Tablayout 类了解一下。

    【讨论】:

    • 您也应该考虑降低禁用选项卡的不透明度,因此看起来仍然无法选择;见my answer
    【解决方案2】:

    另一个技巧:

    您可以在 tablayout 上放置另一个空白透明视图,直到满足您的要求。当您需要启用/显示选项卡时,只需隐藏空白视图即可。

    【讨论】:

      【解决方案3】:

      位置启用特定标签:

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

      位置禁用标签:

       tabStrip.getChildAt(position).setOnTouchListener((v,event)->true);
      

      【讨论】:

      • 为什么?你能显示代码吗?你有什么要求?
      • 我的意思是它只禁用触摸事件用户仍然可以通过滚动视图寻呼机进行。所以如果 userpager 是可滚动的,这不是完美的选择。
      • 你看错问题了,看看这个stackoverflow.com/questions/29442216/…
      【解决方案4】:

      标签点击监听器实现了 3 种方法,其中之一是 onTabSelected() 放置一个布尔条件来检查您的片段是否已初始化。然后,如果满足该条件,则允许进行交易。 还要在您的片段代码之后初始化选项卡

      【讨论】:

      • @war_hero,如何防止tablayout将触摸转发到viewpager?
      • 这是禁用它的方法。 val tabStrip = reporting_tabs.getChildAt(0) as LinearLayout for (i in 0 until tabStrip.childCount) { tabStrip.getChildAt(i).setOnTouchListener { v, event -> true } }
      【解决方案5】:

      这里有 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")
      

      【讨论】:

        【解决方案6】:

        如果你想禁用标签,你只需要使用自定义视图

        首先,创建您的自定义布局(以 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)
          }
        }
        

        【讨论】:

          【解决方案7】:

          我发现最好的解决方案是创建一个TabLayout 的子代,在使用setEnabled(false) 时禁用触摸交互。 (注意下面是 Kotlin)

          class NonTouchableTabLayout(context: Context,attributeSet: AttributeSet) : TabLayout(context, attributeSet) {
          
              override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
                  return !isEnabled
              }
          }
          

          通过这种方式,您还可以获得将其设置为禁用的 UI 更改,并且您避免像其他一些答案所建议的那样依赖 TabLayout 的内部工作(可能会改变)。

          【讨论】:

            【解决方案8】:

            如果您要禁用 TabLayout 上的一个选项卡按钮,请尝试以下代码:

            tabHost.getTabWidget().getChildTabViewAt(your_index).setEnabled(false);
            

            【讨论】:

            • 是不是tabhost和我之前用的tablayout不一样?
            • 您可以尝试如果有任何问题然后告诉我我会检查它。
            • 我认为设计支持库中的 tabhost 和 tablayout 是完全不同的。所以我不能用这个方法。
            • 让我再检查一次。
            猜你喜欢
            • 1970-01-01
            • 2016-01-02
            • 2015-09-28
            • 2019-02-28
            • 2015-08-28
            • 2018-02-11
            • 1970-01-01
            • 2015-08-25
            • 1970-01-01
            相关资源
            最近更新 更多