我正在使用设计库提供的新类:TabLayout。而且我想在特定的情况下我正在使用的那个不能再改变标签了。
我设法在其viewpager上禁用滑动,但我无法通过点击标签来弄清楚如何禁用页面更改。
提前感谢。
答案 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)
您可以使用循环标签,并使用此功能禁用所有标签
答案 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
您可以打开和关闭点击功能(通过设置true
或false
)。使用相同的方法,还可以修改可见性, alpha , backgroundColor 等。