在 TabLayout 中禁用标签
Disable Tabs in TabLayout
我在我的应用程序中使用了来自最新设计支持库的 TabLayout
。这些选项卡附加到一个 viewpager,它为每个选项卡加载片段。我想禁用所有选项卡,直到 viewpager 加载用户选择的选项卡的片段。我无法禁用 tablayout 或使其不可点击。我曾使用 setEnabled(false)
和 setClickable(false)
但它不起作用。我可以使用 setVisiblity(View.GONE)
使其不可见,但我希望选项卡始终可见。
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.near_me_hover).setTag(1));
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.all_hostels).setTag(2));
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.top_five).setTag(3));
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.advanced_search).setTag(4));
tabLayout.setEnabled(false);
tabLayout.setClickable(false);
XML
android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.15"
android:scrollbars="horizontal"
android:splitMotionEvents="false" >
@Override
public void onTabSelected(TabLayout.Tab tab) {
switch (tab.getPosition()) {
case 0:
viewPager.setCurrentItem(tab.getPosition());
tab.setIcon(R.drawable.near_me_hover);
break;
case 1:
viewPager.setCurrentItem(tab.getPosition());
tab.setIcon(R.drawable.all_hostels_hover);
break;
case 2:
viewPager.setCurrentItem(tab.getPosition());
tab.setIcon(R.drawable.top_five_hover);
break;
case 3:
viewPager.setCurrentItem(tab.getPosition());
tab.setIcon(R.drawable.advanced_search_hover);
break;
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
switch (tab.getPosition()) {
case 0:
tab.setIcon(R.drawable.near_me);
break;
case 1:
tab.setIcon(R.drawable.all_hostels);
break;
case 2:
tab.setIcon(R.drawable.top_five);
break;
case 3:
tab.setIcon(R.drawable.advanced_search);
break;
}
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
tabLayout.getTabAt(position).select();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
选项卡点击侦听器实现了 3 种方法,其中之一是 onTabSelected() 放置一个布尔条件来检查您的片段是否已初始化。然后,如果满足该条件,则允许进行交易。
在片段代码
之后也初始化选项卡
如果你想在 TabLayout 上禁用一个标签按钮,那么试试这个代码:
tabHost.getTabWidget().getChildTabViewAt(your_index).setEnabled(false);
另一个技巧:
您可以在 tablayout 上放置另一个空白透明视图,直到满足您的要求。当您需要 enable/show 选项卡时,只需隐藏空白视图即可。
如果你想禁用标签,你只需要使用一个customView
首先,创建您的自定义布局(以 textView 为例)
v_tabview.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tabItemView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:maxLines="1"
android:textColor="@drawable/selector_tab" />
创建选择器,用于更改状态 enable/disable(更改颜色)
selector_tab.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#9e9e9e" android:state_enabled="false" /> //gray
<item android:color="#64b246" android:state_enabled="true" /> //green
</selector>
然后对其充气,设置名称并添加到 tabLayout
arrayStringNames.forEach { name ->
val textView: TextView = inflater.inflate(R.layout.v_tabview, tabLayout, false) as TextView
textView.text = name
val tab = tabLayout.newTab()
tab.customView = textView
tabLayout.addTab(tab)
}
最后,一个魔术!在该示例代码中,我禁用了所有选项卡。如果需要禁用第二个和第三个选项卡,请循环检查 "index" 并在需要时禁用
for (index in 0 until tabLayout.tabCount) {
((tabLayout.getTabAt(index)?.customView) as? TextView)?.let { textView ->
textView.isEnabled = enable //boolean
(textView.parent as View).enable(enable)
}
}
你可以创建一个 util 函数,我在 Kotlin 中的乐趣:
fun disableTabAt(tablayout: TabLayout?, index: Int) {
(tablayout?.getChildAt(0) as? ViewGroup)?.getChildAt(index)?.isEnabled = false
}
当您想对视图进行操作时,您可以调试或单击父视图以了解它是如何创建的。通过这种方式,您可以做任何您想做的事情。对于这种情况,可以去Tablayoutclass了解一下。
在位置启用特定选项卡:
LinearLayout tabStrip = ((LinearLayout)tabLayout.getChildAt(0));
tabStrip.getChildAt(position).setOnTouchListener((v,event)->false);
禁用位于位置的选项卡:
tabStrip.getChildAt(position).setOnTouchListener((v,event)->true);
这里有 2 个辅助函数 (kotlin),用于通过传递名称来禁用和启用 TabItem。
使用com.google.android.material:material:1.3.0-alpha02
测试
fun disableTabItemAt(tabLayout: TabLayout?, tabText: String) {
(tabLayout?.getChildAt(0) as? ViewGroup)?.children?.iterator()?.forEach {
if((it as TabLayout.TabView).tab?.text == tabText) {
it.isEnabled = false
it.alpha = 0.5f
}
}
}
fun enableTabItemAt(tabLayout: TabLayout?, tabText: String) {
(tabLayout?.getChildAt(0) as? ViewGroup)?.children?.iterator()?.forEach {
if((it as TabLayout.TabView).tab?.text == tabText) {
it.isEnabled = true
it.alpha = 1f
}
}
}
因此,如果您的选项卡名称是固定的,那么您可以这样做
disableTabItemAt(tabLayout, "Tab1")
// later enable it
enableTabItemAt(tabLayout, "Tab1")
我发现最好的解决方案是创建 TabLayout
的子项,在使用 setEnabled(false)
时禁用触摸交互。
(注意下面是 Kotlin)
class NonTouchableTabLayout(context: Context,attributeSet: AttributeSet) : TabLayout(context, attributeSet) {
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
return !isEnabled
}
}
通过这种方式,您还可以获得 UI 将其设置为禁用的更改,并且您可以避免像其他一些答案所建议的那样依赖 TabLayout 的内部工作方式(可能会更改)。
我在我的应用程序中使用了来自最新设计支持库的 TabLayout
。这些选项卡附加到一个 viewpager,它为每个选项卡加载片段。我想禁用所有选项卡,直到 viewpager 加载用户选择的选项卡的片段。我无法禁用 tablayout 或使其不可点击。我曾使用 setEnabled(false)
和 setClickable(false)
但它不起作用。我可以使用 setVisiblity(View.GONE)
使其不可见,但我希望选项卡始终可见。
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.near_me_hover).setTag(1));
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.all_hostels).setTag(2));
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.top_five).setTag(3));
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.advanced_search).setTag(4));
tabLayout.setEnabled(false);
tabLayout.setClickable(false);
XML
android.support.design.widget.TabLayout
android:id="@+id/tabLayout" android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.15"
android:scrollbars="horizontal"
android:splitMotionEvents="false" >
@Override
public void onTabSelected(TabLayout.Tab tab) {
switch (tab.getPosition()) {
case 0:
viewPager.setCurrentItem(tab.getPosition());
tab.setIcon(R.drawable.near_me_hover);
break;
case 1:
viewPager.setCurrentItem(tab.getPosition());
tab.setIcon(R.drawable.all_hostels_hover);
break;
case 2:
viewPager.setCurrentItem(tab.getPosition());
tab.setIcon(R.drawable.top_five_hover);
break;
case 3:
viewPager.setCurrentItem(tab.getPosition());
tab.setIcon(R.drawable.advanced_search_hover);
break;
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
switch (tab.getPosition()) {
case 0:
tab.setIcon(R.drawable.near_me);
break;
case 1:
tab.setIcon(R.drawable.all_hostels);
break;
case 2:
tab.setIcon(R.drawable.top_five);
break;
case 3:
tab.setIcon(R.drawable.advanced_search);
break;
}
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
tabLayout.getTabAt(position).select();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
选项卡点击侦听器实现了 3 种方法,其中之一是 onTabSelected() 放置一个布尔条件来检查您的片段是否已初始化。然后,如果满足该条件,则允许进行交易。 在片段代码
之后也初始化选项卡如果你想在 TabLayout 上禁用一个标签按钮,那么试试这个代码:
tabHost.getTabWidget().getChildTabViewAt(your_index).setEnabled(false);
另一个技巧:
您可以在 tablayout 上放置另一个空白透明视图,直到满足您的要求。当您需要 enable/show 选项卡时,只需隐藏空白视图即可。
如果你想禁用标签,你只需要使用一个customView
首先,创建您的自定义布局(以 textView 为例)
v_tabview.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tabItemView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:maxLines="1"
android:textColor="@drawable/selector_tab" />
创建选择器,用于更改状态 enable/disable(更改颜色)
selector_tab.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#9e9e9e" android:state_enabled="false" /> //gray
<item android:color="#64b246" android:state_enabled="true" /> //green
</selector>
然后对其充气,设置名称并添加到 tabLayout
arrayStringNames.forEach { name ->
val textView: TextView = inflater.inflate(R.layout.v_tabview, tabLayout, false) as TextView
textView.text = name
val tab = tabLayout.newTab()
tab.customView = textView
tabLayout.addTab(tab)
}
最后,一个魔术!在该示例代码中,我禁用了所有选项卡。如果需要禁用第二个和第三个选项卡,请循环检查 "index" 并在需要时禁用
for (index in 0 until tabLayout.tabCount) {
((tabLayout.getTabAt(index)?.customView) as? TextView)?.let { textView ->
textView.isEnabled = enable //boolean
(textView.parent as View).enable(enable)
}
}
你可以创建一个 util 函数,我在 Kotlin 中的乐趣:
fun disableTabAt(tablayout: TabLayout?, index: Int) {
(tablayout?.getChildAt(0) as? ViewGroup)?.getChildAt(index)?.isEnabled = false
}
当您想对视图进行操作时,您可以调试或单击父视图以了解它是如何创建的。通过这种方式,您可以做任何您想做的事情。对于这种情况,可以去Tablayoutclass了解一下。
在位置启用特定选项卡:
LinearLayout tabStrip = ((LinearLayout)tabLayout.getChildAt(0));
tabStrip.getChildAt(position).setOnTouchListener((v,event)->false);
禁用位于位置的选项卡:
tabStrip.getChildAt(position).setOnTouchListener((v,event)->true);
这里有 2 个辅助函数 (kotlin),用于通过传递名称来禁用和启用 TabItem。
使用com.google.android.material:material:1.3.0-alpha02
fun disableTabItemAt(tabLayout: TabLayout?, tabText: String) {
(tabLayout?.getChildAt(0) as? ViewGroup)?.children?.iterator()?.forEach {
if((it as TabLayout.TabView).tab?.text == tabText) {
it.isEnabled = false
it.alpha = 0.5f
}
}
}
fun enableTabItemAt(tabLayout: TabLayout?, tabText: String) {
(tabLayout?.getChildAt(0) as? ViewGroup)?.children?.iterator()?.forEach {
if((it as TabLayout.TabView).tab?.text == tabText) {
it.isEnabled = true
it.alpha = 1f
}
}
}
因此,如果您的选项卡名称是固定的,那么您可以这样做
disableTabItemAt(tabLayout, "Tab1")
// later enable it
enableTabItemAt(tabLayout, "Tab1")
我发现最好的解决方案是创建 TabLayout
的子项,在使用 setEnabled(false)
时禁用触摸交互。
(注意下面是 Kotlin)
class NonTouchableTabLayout(context: Context,attributeSet: AttributeSet) : TabLayout(context, attributeSet) {
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
return !isEnabled
}
}
通过这种方式,您还可以获得 UI 将其设置为禁用的更改,并且您可以避免像其他一些答案所建议的那样依赖 TabLayout 的内部工作方式(可能会更改)。