Change the font of tab text in android design support TabLayout

前端 未结 18 1472
执念已碎
执念已碎 2020-11-27 13:38

I\'m trying to work on the new TabLayout from the android design library.

I want to change tab text to custom font. And,I tried to sear

相关标签:
18条回答
  • 2020-11-27 14:22

    And here is my implementation in Kotlin that also allow change font for selected and unselected tabs.

    class FontTabLayout @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        @AttrRes defStyleAttr: Int = 0
    ) : TabLayout(context, attrs, defStyleAttr) {
    
        private var textSize = 14f
    
        private var defaultSelectedPosition = 0
    
        private var selectedTypeFace: Typeface? = ResourcesCompat.getFont(context, R.font.muli_bold)
        private var normalTypeFace: Typeface? = ResourcesCompat.getFont(context, R.font.muli_regular)
    
        @ColorInt private var selectedColor = 0
        @ColorInt private var normalTextColor = 0
    
        init {
            attrs?.let { initAttrs(it) }
            addOnTabSelectedListener()
        }
    
        private fun initAttrs(attrs: AttributeSet) {
            val a = context.obtainStyledAttributes(attrs, R.styleable.FontTabLayout)
    
            textSize = a.getDimensionPixelSize(R.styleable.FontTabLayout_textSize, 14).toFloat()
    
            defaultSelectedPosition = a.getInteger(R.styleable.FontTabLayout_defaultSelectedPosition, 0)
            val selectedResourceId = a.getResourceId(R.styleable.FontTabLayout_selectedTypeFace, R.font.muli_bold)
            val normalResourceId = a.getResourceId(R.styleable.FontTabLayout_normalTypeFace, R.font.muli_regular)
    
            selectedColor = a.getColor(com.google.android.material.R.styleable.TabLayout_tabSelectedTextColor, 0)
            normalTextColor = a.getColor(R.styleable.FontTabLayout_normalTextColor, 0)
    
            selectedTypeFace = ResourcesCompat.getFont(context, selectedResourceId)
            normalTypeFace = ResourcesCompat.getFont(context, normalResourceId)
    
            a.recycle()
        }
    
        private fun addOnTabSelectedListener() {
            addOnTabSelectedListener(object : OnTabSelectedListenerAdapter() {
    
                override fun onTabUnselected(tab: Tab?) {
                    getCustomViewFromTab(tab)?.apply {
                        setTextColor(normalTextColor)
                        typeface = normalTypeFace
                    }
                }
    
                override fun onTabSelected(tab: Tab?) {
    
                    getCustomViewFromTab(tab)?.apply {
                        setTextColor(selectedColor)
                        typeface = selectedTypeFace
                    }
                }
    
                private fun getCustomViewFromTab(tab: Tab?) = tab?.customView as? AppCompatTextView
    
            })
        }
    
        override fun setupWithViewPager(viewPager: ViewPager?, autoRefresh: Boolean) {
            super.setupWithViewPager(viewPager, autoRefresh)
            addViews(viewPager)
        }
    
        private fun addViews(viewPager: ViewPager?) {
            for (i in 0 until tabCount) {
                val customTabView = getCustomTabView(i).apply {
                    typeface = if (i == defaultSelectedPosition) selectedTypeFace else normalTypeFace
                    val color = if (i == defaultSelectedPosition) selectedColor else normalTextColor
                    setTextColor(color)
                    text = viewPager?.adapter?.getPageTitle(i)
                }
    
                getTabAt(i)?.customView = customTabView
            }
        }
    
        private fun getCustomTabView(position: Int): AppCompatTextView {
            return AppCompatTextView(context).apply {
                gravity = Gravity.CENTER
                textSize = this@FontTabLayout.textSize
                text = position.toString()
            }
        }
    }
    

    in attrs.xml:

    <declare-styleable name="FontTabLayout">
        <attr name="normalTextColor" format="reference|color" />
        <attr name="textSize" format="dimension" />
        <attr name="defaultSelectedPosition" format="integer" />
        <attr name="selectedTypeFace" format="reference" />
        <attr name="normalTypeFace" format="reference" />
    </declare-styleable>
    
    0 讨论(0)
  • 2020-11-27 14:23

    The following method will change font in entire ViewGroup recursively. I chose this method because you don't have to care about inner structure of TabLayout. I'm using Calligraphy library to set a font.

    void changeFontInViewGroup(ViewGroup viewGroup, String fontPath) {
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            View child = viewGroup.getChildAt(i);
            if (TextView.class.isAssignableFrom(child.getClass())) {
                CalligraphyUtils.applyFontToTextView(child.getContext(), (TextView) child, fontPath);
            } else if (ViewGroup.class.isAssignableFrom(child.getClass())) {
                changeFontInViewGroup((ViewGroup) viewGroup.getChildAt(i), fontPath);
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 14:25

    If you are using TabLayout and you want to change the font you have to add a new for loop to the previous solution like this:

    private void changeTabsFont() {
        ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
            int tabsCount = vg.getChildCount();
            for (int j = 0; j < tabsCount; j++) {
                ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
                int tabChildsCount = vgTab.getChildCount();
                for (int i = 0; i < tabChildsCount; i++) {
                    View tabViewChild = vgTab.getChildAt(i);
                    if (tabViewChild instanceof TextView) {
                        ((TextView) tabViewChild).setTypeface(Font.getInstance().getTypeFace(), Typeface.NORMAL);
                    }
            }
        }
    } 
    

    Please refer to change font style in action bar tabs using sherlock

    0 讨论(0)
  • 2020-11-27 14:25

    You can use this, it works for me.

     private void changeTabsFont() {
        ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
        int tabsCount = vg.getChildCount();
        for (int j = 0; j < tabsCount; j++) {
            ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
            int tabChildsCount = vgTab.getChildCount();
            for (int i = 0; i < tabChildsCount; i++) {
                View tabViewChild = vgTab.getChildAt(i);
                if (tabViewChild instanceof TextView) {
                    AssetManager mgr = getActivity().getAssets();
                    Typeface tf = Typeface.createFromAsset(mgr, "fonts/Roboto-Regular.ttf");//Font file in /assets
                    ((TextView) tabViewChild).setTypeface(tf);
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 14:25

    With kotlin extension functions use this:

     fun TabLayout.setFontSizeAndColor(typeface: Typeface, @DimenRes textSize: Int, @ColorRes textColor: Int) {
    val viewGroup: ViewGroup = this.getChildAt(0) as ViewGroup
    val tabsCount: Int = viewGroup.childCount
    for (j in 0 until tabsCount) {
        val viewGroupTab: ViewGroup = viewGroup.getChildAt(j) as ViewGroup
        val tabChildCount: Int = viewGroupTab.childCount
        for (i in 0 until tabChildCount) {
            val tabViewChild: View = viewGroupTab.getChildAt(i) as View
            if ( tabViewChild is TextView) {
                tabViewChild.typeface = typeface
                tabViewChild.gravity = Gravity.FILL
                tabViewChild.maxLines = 1
                tabViewChild.setTextSize(TypedValue.COMPLEX_UNIT_PX, this.resources.getDimension(textSize))
                tabViewChild.setTextColor(ContextCompat.getColor(this.context, textColor))
            }
        }
    }
    

    }

    0 讨论(0)
  • 2020-11-27 14:33
    I think this is easier way.
    
    <android.support.design.widget.TabLayout
       android:id="@+id/tabs"
       app:tabTextColor="@color/lightPrimary"
       app:tabSelectedTextColor="@color/white"
       style="@style/CustomTabLayout"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"/>
    <style name="CustomTabLayout" parent="Widget.Design.TabLayout">
       <item name="tabMaxWidth">20dp</item>
       <item name="tabMode">scrollable</item>
       <item name="tabIndicatorColor">?attr/colorAccent</item>
       <item name="tabIndicatorHeight">2dp</item>
       <item name="tabPaddingStart">12dp</item>
       <item name="tabPaddingEnd">12dp</item>
       <item name="tabBackground">?attr/selectableItemBackground</item>
       <item name="tabTextAppearance">@style/CustomTabTextAppearance</item>
       <item name="tabSelectedTextColor">?android:textColorPrimary</item>
    </style>
    <style name="CustomTabTextAppearance" parent="TextAppearance.Design.Tab">
       <item name="android:textSize">16sp</item>
       <item name="android:textStyle">bold</item>
       <item name="android:textColor">?android:textColorSecondary</item>
       <item name="textAllCaps">false</item>
    </style>
    
    0 讨论(0)
提交回复
热议问题