I\'m using the new class provided by the design library : TabLayout. And I want in specific cases that the one I\'m using can\'t change tab anymore.
I manage to disa
I found a similar answer that is a little more simple and also allows you to re-enable the tabs later if you wanted to without having to deal with overriding the onTouch event.
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);
}
And if you want to re-enable the tabs just set tabStrip.setEnabled and setClickable for the child elements to true
LinearLayout tabStrip = ((LinearLayout)tabLayout.getChildAt(0));
tabStrip.setEnabled(true);
for(int i = 0; i < tabStrip.getChildCount(); i++) {
tabStrip.getChildAt(i).setClickable(true);
}
If you are using a custom view for the Tab, you can use View#getParent() to get a reference to the Tab's View if you don't want to look through the ViewGroups.
Note: Using the custom view itself instead of the parent may not work because it can have margin, allowing the user to click in the empty space and change the tab still.
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);
The OnTouchListener way and the setEnabled() way do different things, but have the same effect. I prefer the one-liner.
Again, this only works if you use a custom view, otherwise the getParent() call will cause a NullPointerException.
Very similar to the answer by pat8719 but just disabling the tabs is sufficient to prevent them from being selected.
TabLayout tabLayout = (TabLayout) mParentView.findViewById(R.id.my_tabs);
TabLayoutUtils.enableTabs( tabLayout, false );
TabLayoutUtils class
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;
}
}
For me the working approach is this:
bool condition = ...
foreach (var view in _tabLayout.Touchables)
view.Clickable = condition;
This is 100% safe, as getTouchables() call is supported since API 1. No need to manually traverse layout or something. I consider it to be much simpler than that of the accepted answer, but only when all the tabs have to be marked not clickable.
P.S.: example is on C#, as I am working with Xamarin, but it is fairly easy to translate it back to Java. Enjoy! =)
Kotlin example:
tabLayout.touchables.forEach { it.isClickable = false }
Java example:
for (View v: tabLayout.getTouchables())
v.setClickable(false);
I had the same problem and I solved it disabling touch event on tabs with the following code:
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;
}
});
}
In my use case, if the user is in a tab and presses one of the buttons, a calculation is launched and I don't want the user to be able to switch tabs until after the calculation is completed. So I used the answer by Vladislav Rishe but modified a little as follows...
In 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);
}
}
So when the user taps the button to make a calculation, just before the calculation logic is called, I call disableTabs()
, then once the calculation is completed and it has been displayed, I call enableTabs()
...