【问题标题】:How to set the app:tabBackground of a tabLayout programmatically?如何以编程方式设置 tabLayout 的 app:tabBackground?
【发布时间】:2017-03-01 15:14:26
【问题描述】:

这是我的代码:这是一个 tabLayout,我 setupWithViewpager

    <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"

以编程方式设置此 tabBackground 非常重要,因为我希望根据用户选择的主题改变颜色

这些是我已经尝试过的,但没有一个有效:

    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));

注意:

这是我在drawable中的tab_color_selector.xml:

<?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>

【问题讨论】:

    标签: android


    【解决方案1】:

    试试这个。

    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);
        }
    }
    

    【讨论】:

      【解决方案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>
      

      【讨论】:

      • 我正在尝试将可绘制对象设置为背景,而不是颜色
      • 抱歉,还是不行。我试图以编程方式设置的背景是 tabBackground,您的代码适用于普通背景
      • 我在我的项目中尝试了这段代码,它可以工作,你能把你的drawable放上去吗?
      • 你想改变tabLayout的背景还是每个tab的背景?
      • 我是选中要突出显示的标签
      【解决方案3】:

      我通过这样做以编程方式更改了“app:tabBackground="@drawable/tab_color_selector"”:

      (我的tab_color_selectorsecond_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;
              }
            }
      
          });
      

      因为这样做改变了我的“点”布局,所以我添加了一个固定的widthandroid:layout_width="50dp" 在我的 TabLayout XML 中)。

      我在所有 tabLayout.getTabAt(X).setIcon(....) 上都有 NPE 警告,但因为我知道有 3 个选项卡,所以我允许自己这样做...(也许使用 for 的解决方案更好?)

      希望这会对某人有所帮助

      ---编辑 1---

      我在 API 28、27 和 19 上进行了测试,但它似乎无法在我的模拟器 API 27 上运行...将在真实设备上尝试其他方法。

      ---编辑 2---

      来自 Ankur 的响应应该是被接受的......在我所有的模拟器上都像魅力一样工作,而且速度更快。

      【讨论】:

        【解决方案4】:

        只需为选项卡使用自定义布局,这是工作示例:

        把这两个方法放到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
        }
        

        和 initTabsView(parent: TabLayout) 在其中初始化 PagerAdapter 本身

        【讨论】:

          【解决方案5】:

          这是唯一对我有用的解决方案!!!

          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)
              }
          }
          

          【讨论】:

            【解决方案6】:

            你可以这样做:

            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();
            }
            

            【讨论】:

              【解决方案7】:

              像这样尝试,我有两种类型的标签布局背景。根据标签计数的大小,它会修改结果

              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());
                  }
              

              【讨论】:

                【解决方案8】:

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

                // 选项卡选择器

                <?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>
                

                // tab_indicator_slected

                <?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>
                

                // 标签指示器默认

                <?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

                 <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) {
                
                            }
                        });
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-10-05
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-04-13
                  相关资源
                  最近更新 更多