【问题标题】:How do I change the text style of a selected tab when using tabLayout?使用 tabLayout 时如何更改选定选项卡的文本样式?
【发布时间】:2015-08-16 03:09:21
【问题描述】:

我想让所选标签的文本变为粗体。我怎样才能通过 xml 或 java 代码来做到这一点,无论哪个更容易。

【问题讨论】:

    标签: android


    【解决方案1】:

    我稍微更改了上面建议的答案,它对我很有用,不需要额外的 .xml 文件,希望它会有所帮助。

    for (int i = 0; i < tabLayout.getTabCount(); i++) {
    
        TabLayout.Tab tab = tabLayout.getTabAt(i);
        if (tab != null) {
    
            TextView tabTextView = new TextView(this);
            tab.setCustomView(tabTextView);
    
            tabTextView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
            tabTextView.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
    
            tabTextView.setText(tab.getText());
    
            // First tab is the selected tab, so if i==0 then set BOLD typeface
            if (i == 0) {
                tabTextView.setTypeface(null, Typeface.BOLD);
            }
    
        }
    
    }
    
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());
    
            TextView text = (TextView) tab.getCustomView();
    
            text.setTypeface(null, Typeface.BOLD);
        }
    
        @Override
        public void onTabUnselected(TabLayout.Tab tab) {
            TextView text = (TextView) tab.getCustomView();
    
            text.setTypeface(null, Typeface.NORMAL);
        }
    
        @Override
        public void onTabReselected(TabLayout.Tab tab) {
    
        }
    
    });
    

    【讨论】:

    • setOnTabSelectedListener 已弃用。请改用addOnTabSelectedListener
    • .setTypeFace(null, .. ) 将删除初始化的字体。如果您想使用特定字体,请使用Typeface typeface = ResourcesCompat.getFont(this, R.font.your_font);
    【解决方案2】:

    如果你使用默认的TabLayout(不是customView),你可以通过getChildAt()方法获取标签的TextView。

    .addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                LinearLayout tabLayout = (LinearLayout)((ViewGroup) mMainTabs.getChildAt(0)).getChildAt(tab.getPosition());
                TextView tabTextView = (TextView) tabLayout.getChildAt(1);
                tabTextView.setTypeface(tabTextView.getTypeface(), Typeface.BOLD);
            }
    
            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                LinearLayout tabLayout = (LinearLayout)((ViewGroup) mMainTabs.getChildAt(0)).getChildAt(tab.getPosition());
                TextView tabTextView = (TextView) tabLayout.getChildAt(1);
                tabTextView.setTypeface(null, Typeface.NORMAL);
            }
    
            @Override
            public void onTabReselected(TabLayout.Tab tab) { }
        });
    

    【讨论】:

    • 这会将字体设置为粗体。但在取消选择时不会将其恢复为 NORMAL 字体??
    • 只有在设置为 NORMAL 时将“tabTextView.getTypeface()”替换为 null 时,此解决方案才有效。
    • @Zoran,您的评论有效。创建 ViewPager 时如何确保第一个/默认选择的选项卡加粗?
    • mMainTabs 来自哪里?
    • @MehdiKaramosly mMainTabs 是 TabLayout
    【解决方案3】:

    我知道这是一个老问题,但我想出了一个更好的解决方案: 我创建了这个OnTabSelectedListener

    class OnTabSelectedBoldListener : TabLayout.OnTabSelectedListener {
        override fun onTabReselected(tab: TabLayout.Tab) {}
    
        override fun onTabUnselected(tab: TabLayout.Tab) {
            val views = arrayListOf<View>()
            tab.view.findViewsWithText(views, tab.text, View.FIND_VIEWS_WITH_TEXT)
            views.forEach { view ->
                if (view is TextView) {
                    TextViewCompat.setTextAppearance(view, R.style.TabTextAppearance)
                }
            }
        }
    
        override fun onTabSelected(tab: TabLayout.Tab) {
            val views = arrayListOf<View>()
            tab.view.findViewsWithText(views, tab.text, View.FIND_VIEWS_WITH_TEXT)
            views.forEach { view ->
                if (view is TextView) {
                    TextViewCompat.setTextAppearance(view, R.style.TabTextAppearance_Selected)
                }
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      有一种方法可以通过使用 Tab CustomView 以编程方式添加粗体,将 TextView 加载到该 CustomView 并在 TextView 上应用样式:

      private TabLayout mTabLayout;
      protected void onCreate(Bundle savedInstanceState) {
          ...
          mTabLayout = (TabLayout) findViewById(R.id.tablayout);
          mTabLayout.setOnTabSelectedListener(new OnTabSelectedListener());
          int tabCount = mTabLayout.getTabCount();
          for (int i = 0; i < tabCount; i++) {
              TabLayout.Tab tab = mTabLayout.getTabAt(i);
              if (tab != null) {
                  TextView tabTextView =
                      (TextView) LayoutInflater.from(this).inflate(R.layout.tab_item, mTabLayout, false);
                  tabTextView.setText(tab.getText());
                  // First tab is the selected tab, so if i==0 then set Tabs_Selected style
                  tabTextView.setTextAppearance(getAppContext(), i == 0 ? R.style.TextAppearance_Tabs_Selected
                                                    : R.style.TextAppearance_Tabs);
                  tab.setCustomView(tabTextView);
              }
          }
      }
      class OnTabSelectedListener implements TabLayout.OnTabSelectedListener {
      
          public void onTabSelected(TabLayout.Tab selectedTab) {
              int tabCount = mTabLayout.getTabCount();
              for (int i = 0; i < tabCount; i++) {
                  TabLayout.Tab tab = mTabLayout.getTabAt(i);
                  View tabView = tab != null ? tab.getCustomView() : null;
                  if (tabView instanceof TextView) {
                      ((TextView) tabView).setTextAppearance(getAppContext(), selectedTab.equals(tab)
                                                                 ? R.style.TextAppearance_Tabs_Selected
                                                                 : R.style.TextAppearance_Tabs);
                  }
              }
          }
      
          @Override
          public void onTabUnselected(TabLayout.Tab tab) {
          }
      
          @Override
          public void onTabReselected(TabLayout.Tab tab) {
          }
      

      这里是 styles.xml 中的条目:

      <style name="TextAppearance.Tabs" parent="TextAppearance.Design.Tab">
          <item name="android:textSize">12sp</item>
          <item name="android:textColor">@android:color/white</item>
      </style>
      
      <style name="TextAppearance.Tabs.Selected">
          <item name="android:textStyle">bold</item>
      </style>
      

      这是布局tab_item:

      <?xml version="1.0" encoding="utf-8"?>
      <TextView
          xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:id="@+id/tab_textview"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          tools:text="Tab 1" />
      

      【讨论】:

        【解决方案5】:

        这是此解决方案的 Kotlin 代码

         for (i in 0..tabLayout.tabCount){
                val tab:TabLayout.Tab? = tabLayout.getTabAt(i)
                if (tab != null){
                    val tabTextView:TextView = TextView(this)
                    tab.customView = tabTextView
        
                    tabTextView.layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT
                    tabTextView.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
        
                    tabTextView.text = tab.text
        
                    if (i == 0){
                        // This set the font style of the first tab
                        tabTextView.setTypeface(null,BOLD)
                        
                    }
                    if (i == 1){
                        // This set the font style of the first tab
        
                        tabTextView.setTypeface(null,NORMAL)
                        
                    }
                }
            }
            tabLayout!!.addOnTabSelectedListener(object: TabLayout.OnTabSelectedListener {
                override fun onTabSelected(tab: TabLayout.Tab?) {
                    viewPager.currentItem = tab!!.position
        
                    val text:TextView = tab.customView as TextView
        
                    
                    text.setTypeface(null,BOLD)
                    
        
        
                }
        
                override fun onTabUnselected(tab: TabLayout.Tab?) {
                    val text:TextView = tab?.customView as TextView
        
        
                    text.setTypeface(null,NORMAL)
                    
        
                }
        
                override fun onTabReselected(tab: TabLayout.Tab?) {
        
                }
        
            })
        

        【讨论】:

          【解决方案6】:

          我应用了上面写的hoi 的答案,用于没有自定义视图的默认 TabLayout。它对我来说效果最好。但我真正需要的是在选择选项卡时将 TabItem 内文本的字体系列更改为更粗体。因此,按照 hoi 的解决方案,我稍微更改了代码以适合我。我留下这个答案以防万一有人试图实现类似的目标:

          private fun addOnTabSelectedListener() {
                  tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
                      override fun onTabReselected(tab: TabLayout.Tab?) {
                          return
                      }
          
                      override fun onTabUnselected(tab: TabLayout.Tab?) {
                          tab?.position?.let {
                              changeSelectedTabItemFontFamily(it, R.font.quicksand_medium)
                          }
                      }
          
                      override fun onTabSelected(tab: TabLayout.Tab?) {
                          tab?.position?.let {
                              changeSelectedTabItemFontFamily(it, R.font.quicksand_bold)
                          }
                      }
                  })
              }
          
          private fun changeSelectedTabItemFontFamily(tabPosition: Int, @FontRes fontFamilyRes: Int) {
                  val linearLayout = (this.tabLayout.getChildAt(0) as ViewGroup).getChildAt(tabPosition) as LinearLayout
                  val tabTextView = linearLayout.getChildAt(1) as TextView
                  val typeface = ResourcesCompat.getFont(context, fontFamilyRes)
                  tabTextView.typeface = typeface
          }
          

          【讨论】:

          • 这对我有用
          【解决方案7】:
                 tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
                  @Override
                  public void onTabSelected(TabLayout.Tab tab) {
                      tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.account_active));
                    if (tab.getPosition()==0){
                        tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.booking_active));
                    }
                    if(tab.getPosition()==1){
                        tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.account_active));
                    }
                  }
          
                  @Override
                  public void onTabUnselected(TabLayout.Tab tab) {
          
                      if (tab.getPosition()==0){
                          tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.booking_deacive));
                      }
                      if(tab.getPosition()==1){
                          tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.account_deactive));
                      }
                  }
          
                  @Override
                  public void onTabReselected(TabLayout.Tab tab) {
          
                      if (tab.getPosition()==0){
                          tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.booking_active));
                      }
                      if(tab.getPosition()==1){
                          tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.account_active));
                      }
                  }
              });
          
              setupTabIcons();
          

          【讨论】:

          • 你可以设置你的风格,你的customView的背景
          【解决方案8】:

          你好朋友试试这个

          先添加这个方法

            private void updateCounter() {
              try {
                  for (int i = 0; i < tabLayout.getTabCount(); i++) {
                      updateTab(tabLayout.getTabAt(i));
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
          

          第二次添加这个方法

             private void updateTab(TabLayout.Tab tab) {
              Method method;
              try {
                  method = TabLayout.Tab.class.getDeclaredMethod("getCustomView");
                  method.setAccessible(true);
          
                  View tabView = (View) method.invoke(tab, new Object[0]);
          
                  TextView tv_title = null;
          
                  if (tabView != null) {
                      tv_title = tabView.findViewById(R.id.tv_title);
                  }
          
                  switch (tab.getPosition()) {
                      case 0:
                          if (tv_title != null) {
                              tv_title.setText(tabTitle[0]);
          
                              if(viewPager.getCurrentItem() == 0){
                                  tv_title.setTypeface(CustomerApplication.getInstance().getMontserratBold());
                              }else{
                                  tv_title.setTypeface(CustomerApplication.getInstance().getMontserratMedium());
                              }
                          }
                          break;
          
                      case 1:
                          if (tv_title != null) {
                              tv_title.setText(tabTitle[1]);
          
                              if(viewPager.getCurrentItem() == 1){
                                  tv_title.setTypeface(CustomerApplication.getInstance().getMontserratBold());
                              }else{
                                  tv_title.setTypeface(CustomerApplication.getInstance().getMontserratMedium());
                              }
                          }
                          break;
                  }
                  tab.setCustomView(tabView);
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
          

          最后一次通话查看寻呼机更改监听器

          private final ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
              @Override
              public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
          
              }
          
              @Override
              public void onPageSelected(int position) {
                  updateCounter();
              }
          
              @Override
              public void onPageScrollStateChanged(int state) {
          
              }
          };
          

          【讨论】:

            【解决方案9】:

            这适用于 JAVA

            tabs.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
                @Override
                public void onTabSelected(TabLayout.Tab tab) {
                    initTabSelection(tab);
            
                    for(int index = 0; index < ((ViewGroup) tab.view).getChildCount(); index++) {
                        View nextChild = ((ViewGroup) tab.view).getChildAt(index);
                        if (nextChild instanceof TextView) {
                            TextView v = (TextView) nextChild;
                            v.setTypeface(null, Typeface.BOLD);
                        }
                    }
                }
            
                @Override
                public void onTabUnselected(TabLayout.Tab tab) {
                    for(int index = 0; index < ((ViewGroup) tab.view).getChildCount(); index++) {
                        View nextChild = ((ViewGroup) tab.view).getChildAt(index);
                        if (nextChild instanceof TextView) {
                            TextView v = (TextView) nextChild;
                            v.setTypeface(null, Typeface.NORMAL);
                        }
                    }
                }
            
                @Override
                public void onTabReselected(TabLayout.Tab tab) { }
            });
            

            【讨论】:

              【解决方案10】:

              在我的情况下,setTypeface 在 tab 初始化后无法正常工作,所以我需要使用 post 方法等待 TextView 布局然后 setTypeface

              tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
                  override fun onTabReselected(tab: TabLayout.Tab?) {
                  }
              
                  override fun onTabUnselected(tab: TabLayout.Tab?) {
                      tab?.let {
                          setStyleForTab(it, Typeface.NORMAL)
                      }
                  }
              
                  override fun onTabSelected(tab: TabLayout.Tab?) {
                      tab?.let {
                          setStyleForTab(it, Typeface.BOLD)
                      }
                  }
              
                  fun setStyleForTab(tab: TabLayout.Tab, style: Int) {
                      tab.view.children.find { it is TextView }?.let { tv ->
                          (tv as TextView).post {
                              tv.setTypeface(null, style)
                          }
                      }
                  }
              })
              

              【讨论】:

                【解决方案11】:

                除了以前的答案,请记住,在修改 onTabUnselected 中的文本样式时,如果在 WRAP_CONTENT 上设置了视图的宽度,则可能需要重新计算视图的宽度

                    @Override
                    public void onTabSelected(TabLayout.Tab tab) {
                            TextView text = (TextView) tab.getCustomView();
                            text.setTypeface(null, Typeface.BOLD); 
                            text.getCustomView().measure(WRAP_CONTENT, WRAP_CONTENT)
                            text.getCustomView().layoutParams.height = measuredHeight
                            text.getCustomView().layoutParams.width = measuredWidth
                    }
                

                【讨论】:

                  猜你喜欢
                  • 2017-02-22
                  • 2015-08-25
                  • 1970-01-01
                  • 2016-08-28
                  • 1970-01-01
                  • 2016-04-06
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多