Подтвердить что ты не робот

Отключить TabLayout

Я использую новый класс, предоставляемый библиотекой дизайна: TabLayout. И я хочу, чтобы в определенных случаях тот, который я использую, больше не может изменять вкладку.

Мне удается отключить прокрутку на своем представлении, но я не могу понять, как отключить изменение страницы, нажав на вкладки.

Спасибо заранее.

4b9b3361

Ответ 1

У меня была та же проблема, и я решил отключить сенсорное событие на вкладках со следующим кодом:

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

Ответ 2

Я нашел аналогичный ответ, который немного более прост, а также позволяет повторно включить вкладки позже, если вы хотите, чтобы не иметь дело с переопределением события 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);
}

Ответ 3

Очень похоже на ответ 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;
    }

}

Ответ 4

Хороший трюк, который вы можете использовать:

создать макет фрейма, который охватывает вид (ы), который вы хотите защитить, от щелчка следующим образом:

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

Этот код создаст и пуст/прозрачный вид поверх вашего представления. Андроид: clickable = "true" перехватит клик и не позволит клику перейти через представление!

Этот хак, вероятно, может быть оптимизирован, но его несколько строк кода для защиты нескольких видов одновременно!

Ответ 5

Для меня рабочий подход заключается в следующем:

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

Это на 100% безопасно, так как вызов getTouchables() поддерживается начиная с API 1. Нет необходимости вручную просматривать макет или что-то в этом роде. Я считаю, что это намного проще, чем в принятом ответе, но только тогда, когда все вкладки должны быть помечены как не кликабельные.

PS: пример на С#, так как я работаю с Xamarin, но его довольно легко перевести обратно на Java. Наслаждайтесь! знак равно

Пример Kotlin:

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

Пример Java:

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

Ответ 6

Если вы используете настраиваемое представление для вкладки, вы можете использовать View # getParent(), чтобы получить ссылку на представление табуляции, если вы не хотите просматривать 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.

Ответ 7

проверьте мой ответ здесь Отключить вкладки в TabLayout

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

Ответ 8

сенсорный список массивов решит эту проблему.

объявить деятельность

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

отключить все вкладки

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

Включить вкладку

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

Ответ 9

Также возможно избежать дочерних щелчков, расширяя класс 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
    }
}

Если вы хотите снова включить клики, просто верните false в методе onInterceptTouchEvent.

Ответ 10

Основываясь на этом отличном решении, если кому-то это нужно в Котлине:

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

Или более элегантное решение с лямбдами

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