如何通过编程方式设置TabLayout中选项卡的app:tabBackground?

13

这是我的代码:它是一个TabLayout,我使用setupWith一个Viewpager

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="sans-serif-light"
        app:tabPaddingEnd="-1dp"
        app:tabBackground="@drawable/tab_color_selector"
        app:tabPaddingStart="-1dp"
        app:tabTextAppearance="@style/MineCustomTabText" />

但是我该如何以编程的方式设置它呢?

 app:tabBackground="@drawable/tab_color_selector"

编程设置选项卡的背景色非常重要,因为我想让颜色根据用户选择的主题而变化。

以下是我已经尝试过的方法,但都不起作用:

    tabLayout.setBackground(getResources().getDrawable(R.drawable.tab_color_selector));
    tabLayout.setBackgroundResource((R.drawable.tab_color_selector));
    tabLayout.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_color_selector));
    tabLayout.setBackground(ContextCompat.getDrawable(this, R.drawable.tab_color_selector));

注意:

这是我的tab_color_selector.xml文件,在drawable目录下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/white" android:state_selected="true" />
    <item android:drawable="@color/blue_alu" />
</selector>
8个回答

11

试试这个。

ViewGroup tabStrip = (ViewGroup) tabLayout.getChildAt(0);
for (int i = 0; i < tabStrip.getChildCount(); i++) {
    View tabView = tabStrip.getChildAt(i);
    if (tabView != null) {
        int paddingStart = tabView.getPaddingStart();
        int paddingTop = tabView.getPaddingTop();
        int paddingEnd = tabView.getPaddingEnd();
        int paddingBottom = tabView.getPaddingBottom();
        ViewCompat.setBackground(tabView, AppCompatResources.getDrawable(tabView.getContext(), tabViewBgResId));
        ViewCompat.setPaddingRelative(tabView, paddingStart, paddingTop, paddingEnd, paddingBottom);
    }
}

3

这是唯一有效的解决方案!!!

binding.tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
    override fun onTabReselected(tab: TabLayout.Tab?) {}
    override fun onTabUnselected(tab: TabLayout.Tab?) {}


    override fun onTabSelected(tab: TabLayout.Tab?) {
     tab.view.background = ResourcesCompat.getDrawable(requireContext().resources,  R.drawable.tab_color_selector, null)
    }
}

2
最初的回答:
我成功地通过以下方法以编程方式更改了“app:tabBackground = @ drawable / tab_color_selector ”:
(我的 tab_color_selector second_tab_color_selector 与您的相似(具有默认颜色和所选颜色的选择器)
TabLayout XML:
    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabDots"
        android:layout_width="50dp"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        app:tabBackground="@drawable/tab_color_selector"
        app:tabGravity="center"
        app:tabIndicatorHeight="0dp" />

onCreate中:
tabLayout.setupWithViewPager(viewPagerFragments, true);
setupViewPager(viewPagerFragments);

我添加了一个TabLayoutOnPageChangeListener: 最初的回答
viewPagerFragments.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout) {

      @Override
      public void onPageSelected(int position) {
        switch (position) {
          case 0:
            //Here my background is white so I need grey dots
            tabLayout.getTabAt(position).setIcon(getResources().getDrawable(R.drawable.tab_color_selector));
            tabLayout.getTabAt(1).setIcon(getResources().getDrawable(R.drawable.tab_color_selector));
            tabLayout.getTabAt(2).setIcon(getResources().getDrawable(R.drawable.tab_color_selector));
            break;

          case 1:
            //Here my background is also white so I need grey dots
            tabLayout.getTabAt(0).setIcon(getResources().getDrawable(R.drawable.tab_color_selector));
            tabLayout.getTabAt(position).setIcon(getResources().getDrawable(R.drawable.tab_color_selector));
            tabLayout.getTabAt(2).setIcon(getResources().getDrawable(R.drawable.tab_color_selector));
            break;

          case 2:
            //Here my background is grey so I need white dots
            tabLayout.getTabAt(0).setIcon(getResources().getDrawable(R.drawable.second_tab_color_selector));
            tabLayout.getTabAt(1).setIcon(getResources().getDrawable(R.drawable.second_tab_color_selector));
            tabLayout.getTabAt(position).setIcon(getResources().getDrawable(R.drawable.second_tab_color_selector));
            break;
        }
      }

    });

因为这样做改变了我添加到"点"布局中的布局,所以我必须设置一个固定的width(在我的TabLayout XML中使用android:layout_width="50dp")。
我在所有tabLayout.getTabAt(X).setIcon(....)上都有NPE警告,但因为我知道有3个选项卡,所以我允许自己这样做...(也许使用for更好?)
希望这能帮助某些人。
---编辑1---
我在API 28、27和19上进行了测试,看起来在我的模拟器API 27上不起作用...将尝试其他方法并在真实设备上测试。
---编辑2---
Ankur的回答应该被接受...在我所有的模拟器上都像魔法一样快速地工作。

2
如果你想改变选中标签的背景,可以使用以下代码:(在设置了viewPager之后设置自定义视图)
    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);    
    tabLayout.setupWithViewPager(mViewPager);
    tabLayout.getTabAt(tabLayout.getSelectedTabPosition()).setCustomView(R.layout.your_layout);

如果您想更改tabLayout的背景,请使用以下内容:
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setBackground(ContextCompat.getDrawable(this, R.drawable.your_drawable));

如果您正在使用API级别> 21,请像这样不使用ContextCompat:
tabLayout.setBackground(getDrawable(R.drawable.badge));

例子:

布局

<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:theme="@style/Toolbar"
        app:popupTheme="@style/Toolbar.Popup" />

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMaxWidth="0dp"
        app:tabGravity="fill"
        app:tabMode="fixed" />

</android.support.design.widget.AppBarLayout>

可绘制对象


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/red" />
</shape>

我正在尝试将可绘制对象设置为背景,而不是颜色。 - TSR
8
抱歉,它仍然无法正常工作。我正在尝试以编程方式设置的背景是一个tabBackground,而您的代码是针对普通背景的。 - TSR
我在我的项目中尝试了这段代码,它可以正常工作。你能提供你的可绘制资源吗? - MarcGV
你想要改变tabLayout的背景还是每个选项卡的背景? - MarcGV
我是被选中的标签页,以突出显示。 - TSR
显示剩余2条评论

1

只需为选项卡使用自定义布局,这里是一个可行的示例:

将以下两个方法放入PagerAdapter中:

   fun initTabsView(parent: TabLayout) {
    val layoutInflater = LayoutInflater.from(parent.context)
    (0 until count).forEach { i ->
        val tab: TabLayout.Tab? = parent.getTabAt(i)
        tab?.customView = getTabView(layoutInflater, i)
    }
}

private fun getTabView(layoutInflater: LayoutInflater, position: Int): View {
    val binding = TabCasinoBinding.inflate(layoutInflater)
    binding.category = categories[position]
    return binding.root
}

并在初始化 PagerAdapter 本身的位置上调用 initTabsView(parent: TabLayout)


0
你可以像这样做:
Field field;
try {
    field = tabLayout.getClass().getDeclaredField("mTabBackgroundResId");
    field.setAccessible(true);
    field.set(tabLayout, R.drawable.tab_background);
} catch (NoSuchFieldException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
}

0
尝试像这样,我有两种选项来设置TabLayout的背景。根据选项卡数量的大小,它会自动调整结果。
Field field;
    try {
        field = tabLayout.getClass().getDeclaredField("tabBackgroundResId");
        field.setAccessible(true);
        if(tabLayout.getTabCount()>=3){
            tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            field.set(tabLayout, R.drawable.tab_color_selector_two);
        } else {
            field.set(tabLayout, R.drawable.tab_color_selector);
            tabLayout.setTabMode(TabLayout.MODE_FIXED);
        }
    } catch (NoSuchFieldException | IllegalAccessException e) {
        Logger.e("TabError",e.getMessage());
    }

-3

首先创建一个选项卡选择器:

// 选项卡选择器

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/tab_indicator_selected" 
android:state_selected="true"></item>
<item android:drawable="@drawable/tab_indicator_default"></item>
</selector>

// 选中的标签指示器

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dp"
android:shape="ring"
android:thickness="4dp"

android:useLevel="false">

<solid android:color="@color/intro_pink"></solid>

// Tab Indicator 默认值

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="ring" android:innerRadius="0dp" 
android:thickness="4dp" android:useLevel="false"

xmlns:android="http://schemas.android.com/apk/res/android">

<solid android:color="@color/white"></solid>
</shape>

将ViewPager与Tab Layout适配器添加到您的布局中。
 <androidx.viewpager.widget.ViewPager
            android:id="@+id/vp_pager"
            android:layout_width="match_parent"
            android:layout_height="@dimen/standard_100"
            android:visibility="visible"></androidx.viewpager.widget.ViewPager>

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center|bottom"
            app:tabBackground="@drawable/tab_selector"
            app:tabGravity="center"
            app:tabIndicatorHeight="0dp">

        </com.google.android.material.tabs.TabLayout>

//onCreate

 @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ViewPager vp = findViewById(R.id.vp_pager);
    TabLayout tb = findViewById(R.id.tab_layout);
    tb.setupWithViewPager(vp);

//如果tb.setupWithViewPager(vp)没有完美地工作,请添加此代码
    vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                  tb.getTabAt(position).select();

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接