禁用TabLayout

时间:2015-07-29 14:00:55

标签: android disabled-control android-tablayout

我正在使用设计库提供的新类:TabLayout。而且我想在特定的情况下我正在使用的那个不能再改变标签了。

我设法在其viewpager上禁用滑动,但我无法通过点击标签来弄清楚如何禁用页面更改。

提前感谢。

11 个答案:

答案 0 :(得分:93)

我遇到了同样的问题,我解决了它使用以下代码禁用选项卡上的触摸事件:

  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;
            }
        });
    }

答案 1 :(得分:35)

我找到了一个类似的答案,这个答案稍微简单一些,如果您愿意,可以在以后重新启用选项卡,而无需处理覆盖onTouch事件。

TabLayout tabLayout = (TabLayout)  mParentView.findViewById(R.id.my_tabs);

LinearLayout tabStrip = ((LinearLayout)tabLayout.getChildAt(0));
tabStrip.setEnabled(false);
for(int i = 0; i < tabStrip.getChildCount(); i++) {
    tabStrip.getChildAt(i).setClickable(false);
}

如果你想重新启用标签,只需将子元素的tabStrip.setEnabled和setClickable设置为true

LinearLayout tabStrip = ((LinearLayout)tabLayout.getChildAt(0));
tabStrip.setEnabled(true);
for(int i = 0; i < tabStrip.getChildCount(); i++) {
    tabStrip.getChildAt(i).setClickable(true);
}

答案 2 :(得分:16)

与pat8719的答案非常相似,但只是禁用标签就足以阻止它们被选中。

TabLayout tabLayout = (TabLayout)  mParentView.findViewById(R.id.my_tabs);
TabLayoutUtils.enableTabs( tabLayout, false );

TabLayoutUtils类

public class TabLayoutUtils {

    public static void enableTabs(TabLayout tabLayout, Boolean enable){
        ViewGroup viewGroup = getTabViewGroup(tabLayout);
        if (viewGroup != null)
            for (int childIndex = 0; childIndex < viewGroup.getChildCount(); childIndex++)
            {
                View tabView = viewGroup.getChildAt(childIndex);
                if ( tabView != null)
                    tabView.setEnabled(enable);
            }
    }

    public static View getTabView(TabLayout tabLayout, int position){
        View tabView = null;
        ViewGroup viewGroup = getTabViewGroup(tabLayout);
        if (viewGroup != null && viewGroup.getChildCount() > position)
            tabView = viewGroup.getChildAt(position);

        return tabView;
    }

    private static ViewGroup getTabViewGroup(TabLayout tabLayout){
        ViewGroup viewGroup = null;

        if (tabLayout != null && tabLayout.getChildCount() > 0 ) {
            View view = tabLayout.getChildAt(0);
            if (view != null && view instanceof ViewGroup)
                viewGroup = (ViewGroup) view;
        }
        return viewGroup;
    }

}

答案 3 :(得分:10)

您可以使用的好方法:

创建一个框架布局,覆盖您要保护的视图,使其免受以下操作的影响:

<FrameLayout
    android:clickable="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

此代码将在视图顶部创建并清空/透明视图。 android:clickable =“true”将拦截点击并阻止点击进入视图!

这个hack可能会被优化,但它的几行代码可以同时保护多个视图!

答案 4 :(得分:5)

对我而言,工作方法是:

bool condition = ...
foreach (var view in _tabLayout.Touchables)
    view.Clickable = condition;

这是100%安全的,因为API 1支持getTouchables()调用。无需手动遍历布局或其他内容。我认为它比接受的答案简单得多,但只有当所有标签都必须标记为不可点击时。

P.S。:示例是在C#上,因为我正在使用Xamarin,但将它转换回Java非常容易。请享用! =)

Kotlin例子:

tabLayout.touchables.forEach { it.isClickable = false }

Java示例:

for (View v: tabLayout.getTouchables())
    v.setClickable(false);

答案 5 :(得分:4)

如果您使用Tab的自定义视图,则可以使用View#getParent()获取对Tab的视图的引用(如果您不想查看ViewGroups)。

注意:使用自定义视图本身而不是父视图可能无效,因为它可以有边距,允许用户单击空白区域并更改标签。

View tabView = (View) tab.getCustomView().getParent();

tabView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return true;
    }
});

//or

tabView.setEnabled(false);

OnTouchListener方式和setEnabled()方式做了不同的事情,但具有相同的效果。我更喜欢单线。

同样,仅在使用自定义视图时才有效,否则getParent()调用将导致NullPointerException。

答案 6 :(得分:1)

在我的用例中,如果用户位于选项卡中并按下其中一个按钮,则会启动计算,并且我不希望用户在计算完成后才能切换选项卡。因此,我使用了弗拉迪斯拉夫·里希(Vladislav Rishe)的答案,但作了如下修改...

JAVA 中:

//'tabLayout' is the variable where you reference your tab layout...
//A container to save the tabs that were disabled
private ArrayList<View> touchablesToRestore = new ArrayList<View>();

public void enableTabs() {
    for(View v: touchablesToRestore){
        v.setClickable(true);
    }
    //After you enable them all, clear the container
    touchablesToRestore.clear();
}

public void disableTabs(){
    for(View v: tabLayout.getTouchables()){
        //Add the tab that is being disabled to the container
        touchablesToRestore.add(v);
        v.setClickable(false);
    }
}

因此,当用户点击按钮进行计算时,在调用计算逻辑之前,我会调用disableTabs(),然后在完成计算并显示计算后,我会调用enableTabs() ...

答案 7 :(得分:0)

在这里Disable Tabs in TabLayout

检查我的答案

您可以使用循环标签,并使用此功能禁用所有标签

答案 8 :(得分:0)

还可以通过扩展TabLayout类并拦截所有触摸事件来避免孩子点击。

class NonTouchableTabLayout : TabLayout {

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

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

如果要再次启用点击,只需在onInterceptTouchEvent方法上返回false。

答案 9 :(得分:0)

基于这种出色的解决方案,如果有人在Kotlin中需要它:

  val tabStrip = mTabLayout.getChildAt(0) as LinearLayout
    for (i in 0..tabStrip.childCount) {
        tabStrip.getChildAt(i).setOnTouchListener(object : View.OnTouchListener{
            override fun onTouch(p0: View?, p1: MotionEvent?): Boolean {
                return true
            }
        })
    }

或更佳的lambda解决方案

mTabLayout.setOnTouchListener {v: View, m: MotionEvent ->
        true
 }

答案 10 :(得分:0)

根据Michele的“已接受的答案”,在科特林中禁用对单个标签的点击:

在包含标签的活动中:

val tabs: TabLayout = findViewById(R.id.tabs)
...

(tabs.getChildAt(0) as LinearLayout).getChildAt(desiredTabPositionHere).isClickable = false

在片段(标签)内部:

(requireActivity().tabs.getChildAt(0) as LinearLayout).getChildAt(desiredTabPositionHere).isClickable = false

您可以打开和关闭点击功能(通过设置truefalse)。使用相同的方法,还可以修改可见性 alpha backgroundColor 等。