it-swarm.com.de

Ändern Sie die Schriftart des Tabulatortextes in Android-Designunterstützung TabLayout

Ich versuche an der neuen TabLayout aus der Android-Designbibliothek zu arbeiten.

Ich möchte den Tabulatortext in benutzerdefinierte Schriftart ändern. Und ich habe versucht, nach Stilen zu suchen, die mit TabLayout verwandt sind, endete aber mit this

Bitte führen Sie aus, wie ich die Textschriftarten der Registerkarte ändern kann.

81
Dory

Erstellen Sie eine TextView aus Java-Code oder XML wie folgt

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:id="@Android:id/text1"
    Android:layout_width="match_parent"
    Android:textSize="15sp"
    Android:textColor="@color/tabs_default_color"
    Android:gravity="center"
    Android:layout_height="match_parent"
/>

Stellen Sie sicher, dass die ID unverändert bleibt, da TabLayout diese ID überprüft, wenn Sie eine benutzerdefinierte Textansicht verwenden

Dann blähen Sie dieses Layout aus dem Code auf, legen Sie die benutzerdefinierte Variable _Typeface für diese Textansicht fest und fügen Sie diese benutzerdefinierte Ansicht der Registerkarte hinzu

for (int i = 0; i < tabLayout.getTabCount(); i++) {
     //noinspection ConstantConditions
     TextView tv = (TextView)LayoutInflater.from(this).inflate(R.layout.custom_tab,null)
     tv.setTypeface(Typeface);       
     tabLayout.getTabAt(i).setCustomView(tv);
}
28
Farmaan Elahi

Wenn Sie TabLayout verwenden und die Schriftart ändern möchten, müssen Sie der vorherigen Lösung eine neue for-Schleife hinzufügen:

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

Bitte beziehen Sie sich auf den Schriftstil in den Aktionsleisten-Registerkarten mithilfe von sherlock ändern

145
praveen Sharma

Erstellen Sie Ihren eigenen benutzerdefinierten Stil und verwenden Sie den übergeordneten Stil als parent="@Android:style/TextAppearance.Widget.TabWidget".

Und in Ihrem Tab-Layout verwenden Sie diesen Stil als app:tabTextAppearance="@style/tab_text".

Beispiel: Stil:

<style name="tab_text" parent="@Android:style/TextAppearance.Widget.TabWidget">
    <item name="Android:fontFamily">@font/poppins_regular</item>
</style>

Beispiel: Tabulatorlayoutkomponente:

<Android.support.design.widget.TabLayout
        Android:id="@+id/tabLayout"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:background="?attr/colorPrimary"
        Android:minHeight="?attr/actionBarSize"
        Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:tabTextAppearance="@style/tab_text" />
51
Milind Mevada

Tolle Antwort von Praveen Sharma. Nur ein kleiner Zusatz: Anstatt changeTabsFont() überall zu verwenden, wo Sie TabLayout brauchen, können Sie einfach Ihre eigene CustomTabLayout verwenden.

import Android.content.Context;
import Android.graphics.Typeface;
import Android.support.design.widget.TabLayout;
import Android.util.AttributeSet;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.TextView;

public class CustomTabLayout extends TabLayout {
    private Typeface mTypeface;

    public CustomTabLayout(Context context) {
        super(context);
        init();
    }

    public CustomTabLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CustomTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/Roboto-Regular.ttf");
    }

    @Override
    public void addTab(Tab tab) {
        super.addTab(tab);

        ViewGroup mainView = (ViewGroup) getChildAt(0);
        ViewGroup tabView = (ViewGroup) mainView.getChildAt(tab.getPosition());

        int tabChildCount = tabView.getChildCount();
        for (int i = 0; i < tabChildCount; i++) {
            View tabViewChild = tabView.getChildAt(i);
            if (tabViewChild instanceof TextView) {
                ((TextView) tabViewChild).setTypeface(mTypeface, Typeface.NORMAL);
            }
        }
    }

}

Und noch etwas .TabView ist eine LinearLayout mit TextView im Inneren (sie kann optional auch ImageView enthalten). So können Sie den Code noch einfacher gestalten:

@Override
public void addTab(Tab tab) {
    super.addTab(tab);

    ViewGroup mainView = (ViewGroup) getChildAt(0);
    ViewGroup tabView = (ViewGroup) mainView.getChildAt(tab.getPosition());
    View tabViewChild = tabView.getChildAt(1);
    ((TextView) tabViewChild).setTypeface(mTypeface, Typeface.NORMAL);
}

Aber ich würde diesen Weg nicht empfehlen. Wenn sich die TabLayout-Implementierung ändert, kann dieser Code nicht ordnungsgemäß funktionieren oder sogar abstürzen.

Eine weitere Möglichkeit zum Anpassen von TabLayout ist das Hinzufügen einer benutzerdefinierten Ansicht. Hier ist das tolle Beispiel .

47
Andrei Aulaska

Die folgende Methode ändert die Schriftart in der gesamten ViewGroup rekursiv. Ich habe diese Methode gewählt, weil Sie sich nicht um die innere Struktur von TabLayout kümmern müssen. Ich verwende Calligraphy library, um eine Schriftart festzulegen.

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

Für die Entwurfsunterstützung 23.2.0 müssen Sie mit setupWithViewPager den Code von addTab (Registerkarte Tab) nach addTab (Registerkarte Tab, boolean setSelected) verschieben.

11
ejw

Nun, ich fand es in 23.4.0 einfach, ohne eine Schleife zu verwenden. Überschreiben Sie einfach addTab (@NonNull Tab, boolean setSelected), wie von @ejw vorgeschlagen.

@Override
public void addTab(@NonNull Tab tab, boolean setSelected) {
    CoralBoldTextView coralTabView = (CoralBoldTextView) View.inflate(getContext(), R.layout.coral_tab_layout_view, null);
    coralTabView.setText(tab.getText());
    tab.setCustomView(coralTabView);

    super.addTab(tab, setSelected);
}

Und hier ist das XML

<?xml version="1.0" encoding="utf-8"?>
<id.co.coralshop.skyfish.ui.CoralBoldTextView
   xmlns:Android="http://schemas.Android.com/apk/res/Android"
   Android:id="@+id/custom_text"
   Android:layout_width="match_parent"
   Android:layout_height="wrap_content"
   Android:ellipsize="end"
   Android:gravity="center"
   Android:singleLine="true"
   Android:textColor="@color/graylove"
   Android:textSize="@dimen/tab_text_size" />

Hoffe es könnte helfen :)

8
elsennov

Sie können dies verwenden, es funktioniert für mich.

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

Wenn Sie mit Andrei geantwortet haben, können Sie das fontface ändern, indem Sie die Klasse TabLayout erweitern. Und wie Penzzz gesagt hat, können Sie dies nicht in der addTab -Methode tun. Überschreiben Sie die onLayout -Methode wie folgt:

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom){
    super.onLayout(changed, left, top, right, bottom);

    final ViewGroup tabStrip = (ViewGroup)getChildAt(0);
    final int tabCount = tabStrip.getChildCount();
    ViewGroup tabView;
    int tabChildCount;
    View tabViewChild;

    for(int i=0; i<tabCount; i++){
        tabView = (ViewGroup)tabStrip.getChildAt(i);
        tabChildCount = tabView.getChildCount();
        for(int j=0; j<tabChildCount; j++){
            tabViewChild = tabView.getChildAt(j);
            if(tabViewChild instanceof AppCompatTextView){
                if(fontFace == null){
                    fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.IranSans));
                }
                ((TextView) tabViewChild).setTypeface(fontFace, Typeface.BOLD);
            }
        }
    }
}

Muss die onLayout-Methode überschreiben, da Sie bei der Verwendung der setupWithViewPager - Methode zum Binden des TabLayout mit dem ViewPager den Tabulatortext entweder mit der setText-Methode oder im PagerAdapter festlegen müssen. Wenn dies der Fall ist, wird die onLayout-Methode aufgerufen die übergeordnete ViewGroup (TabLayout), und hier können Sie die Einstellung von fontface setzen. (Das Ändern eines TextView-Texts führt zum Aufruf der onLayout-Methode des übergeordneten Elements - Ein tabView hat zwei Kinder, eines ist ImageView, ein anderes ist TextView.)

Eine andere Lösung:

Zunächst diese Codezeilen:

    if(fontFace == null){
        fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.IranSans));
    }

In obiger Lösung sollte außerhalb von zwei Schleifen geschrieben werden.

Eine bessere Lösung für API> = 16 ist jedoch die Verwendung von Android: fontFamily:

Erstellen Sie eine Android Resource Directory - benannte Schriftart und kopieren Sie die gewünschte Schriftart in das Verzeichnis.

Dann verwenden Sie diese Stile:

<style name="tabLayoutTitles">
    <item name="Android:textColor">@color/white</item>
    <item name="Android:textSize">@dimen/appFirstFontSize</item>
    <item name="Android:fontFamily">@font/vazir_bold</item>
</style>

<style name="defaultTabLayout">
    <item name="Android:layout_width">match_parent</item>
    <item name="Android:layout_height">@dimen/defaultTabLayoutHeight</item>
    <item name="Android:gravity">right</item>
    <item name="tabTextAppearance">@style/tabLayoutTitles</item>
    <item name="tabSelectedTextColor">@color/white</item>
    <item name="tabIndicatorColor">@color/white</item>
    <item name="tabIndicatorHeight">@dimen/accomTabIndicatorHeight</item>
    <item name="tabMode">fixed</item>
    <item name="tabGravity">fill</item>
    <item name="tabBackground">@drawable/rectangle_white_ripple</item>
    <item name="Android:background">@color/colorPrimary</item>
</style>
5
Arash

Verwenden Sie die Support Library 26+, um die Unterstützung von Schriftarten in der Funktion XML auf Geräten zu verwenden, auf denen Android 4.1 (API-Ebene 16) oder höher ausgeführt wird.

  1. Klicken Sie mit der rechten Maustaste auf den Ordner res
  2. Neu -> Android-Ressourcenverzeichnis -> Schriftart auswählen -> OK
  3. Legen Sie Ihre myfont.ttf-Datei in den neu erstellten Zeichensatzordner ab

Am res/values/styles.xml hinzufügen:

<style name="customfontstyle" parent="@Android:style/TextAppearance.Small">
    <item name="Android:fontFamily">@font/myfont</item>
</style>

Fügen Sie in der Layoutdatei eine App hinzu: tabTextAppearance = "@ style/customfontstyle",

<Android.support.design.widget.TabLayout
    Android:id="@+id/tabs"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    app:tabGravity="fill"
    app:tabTextAppearance="@style/customfontstyle"
    app:tabMode="fixed" />

Bitte beziehen Sie sich auf [Schriftarten in XML]. ( https://developer.Android.com/guide/topics/ui/look-and-feel/fonts-in-xml )

5
Thomas V J

Meine Resolve-Methode wie folgt, ändern Sie den Text der angegebenen Registerkarte, 

 ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
 ViewGroup vgTab = (ViewGroup) vg.getChildAt(1);
 View tabViewChild = vgTab.getChildAt(1);
 if (tabViewChild instanceof TextView) {
      ((TextView) tabViewChild).setText(str);
 }
3
Smish jack

Kotlin Erweiterung, die für mich funktionierte:

fun TabLayout.setFont(font: FontUtils.Fonts) {
    val vg = this.getChildAt(0) as ViewGroup
    for (i: Int in 0..vg.childCount) {
        val vgTab = vg.getChildAt(i) as ViewGroup?
        vgTab?.let {
            for (j: Int in 0..vgTab.childCount) {
                val tab = vgTab.getChildAt(j)
                if (tab is TextView) {
                    tab.typeface = FontUtils.getTypeFaceByFont(FontUtils.Fonts.BOLD, context)
                }
            }
        }
    }
}

Mein 2p, Kotlin mit Referenzprüfung, überall anwendbar, da es aufhört, wenn etwas nicht stimmt.

private fun setTabLayouFont(tabLayout: TabLayout) {
    val viewGroupTabLayout = tabLayout.getChildAt(0) as? ViewGroup?
    (0 until (viewGroupTabLayout?.childCount ?: return))
            .map { viewGroupTabLayout.getChildAt(it) as? ViewGroup? }
            .forEach { viewGroupTabItem ->
                (0 until (viewGroupTabItem?.childCount ?: return))
                        .mapNotNull { viewGroupTabItem.getChildAt(it) as? TextView }
                        .forEach { applyDefaultFontToTextView(it) }
            }
}
1
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
sudhakara

Und hier ist meine Implementierung in Kotlin, die auch das Ändern der Schriftart für ausgewählte und nicht ausgewählte Registerkarten ermöglicht.

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 = [email protected]
            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
Yvgen

Verwenden Sie bei Kotlin-Erweiterungsfunktionen Folgendes:

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

}