Отключить TabLayout
Я использую новый класс, предоставляемый библиотекой дизайна: TabLayout. И я хочу, чтобы в определенных случаях тот, который я использую, больше не может изменять вкладку.
Мне удается отключить прокрутку на своем представлении, но я не могу понять, как отключить изменение страницы, нажав на вкладки.
Спасибо заранее.
Ответы
Ответ 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
}