使用tabLayout时如何更改所选选项卡的文本样式?

时间:2015-08-16 03:09:21

标签: android

我想将所选标签的文字设为粗体。如何通过xml或java代码执行此操作,无论更简单。

11 个答案:

答案 0 :(得分:17)

我改变了上面建议的答案,它对我很有用,不需要额外的.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) {

    }

});

答案 1 :(得分:6)

如果使用默认的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(tabTextView.getTypeface(), Typeface.NORMAL);
        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) { }
    });

答案 2 :(得分:2)

有一种方法可以通过使用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" />

答案 3 :(得分:1)

我知道这是一个老问题,但是我想出了一个更好的解决方案: 我创建了这个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 :(得分:1)

这是此解决方案的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?) {

        }

    })

答案 5 :(得分:0)

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

答案 6 :(得分:0)

你好朋友,请尝试

  

首先添加此方法

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

    }
};

答案 7 :(得分:0)

我应用了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
}

答案 8 :(得分:0)

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

答案 9 :(得分:0)

在我的情况下,setTypeface 在 tab init 后不能立即工作,所以我需要使用 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)
            }
        }
    }
})

答案 10 :(得分:-1)

除了先前的答案外,请记住,在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
    }