J'essaie de travailler sur la nouvelle TabLayout
de la bibliothèque de conception Android.
Je souhaite modifier le texte de l'onglet en police personnalisée. Et, j'ai essayé de chercher un style lié à TabLayout
, mais j'ai fini par this .
S'il vous plaît guider comment puis-je changer les polices de texte de tabulation.
Créez un TextView à partir de Java Code ou XML comme ceci
<?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"
/>
Assurez-vous de conserver l'ID tel qu'il est ici car le TabLayout vérifie cet ID si vous utilisez l'affichage de texte personnalisé.
Ensuite, à partir du code, gonflez cette disposition, définissez la variable Typeface
sur cette vue textuelle et ajoutez cette vue personnalisée à l'onglet.
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);
}
Si vous utilisez TabLayout
et que vous souhaitez modifier la police, vous devez ajouter une nouvelle boucle for à la solution précédente, comme ceci:
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);
}
}
}
}
Veuillez vous référer à changer le style de police dans les onglets de la barre d’action en utilisant sherlock
Créez votre propre style personnalisé et utilisez le style parent comme parent="@Android:style/TextAppearance.Widget.TabWidget"
Et dans votre disposition d'onglet utilisez ce style comme app:tabTextAppearance="@style/tab_text"
Exemple: Style:
<style name="tab_text" parent="@Android:style/TextAppearance.Widget.TabWidget">
<item name="Android:fontFamily">@font/poppins_regular</item>
</style>
Exemple: Composant de présentation d'onglets:
<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" />
Grande réponse de Praveen Sharma. Juste un petit ajout: Au lieu d'utiliser changeTabsFont()
partout où vous avez besoin de TabLayout
, vous pouvez simplement utiliser votre propre CustomTabLayout
.
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);
}
}
}
}
Et encore une chose .TabView
est une LinearLayout
avec TextView
à l'intérieur (elle peut aussi éventuellement contenir ImageView
). Vous pouvez donc rendre le code encore plus simple:
@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);
}
Mais je ne recommanderais pas de cette façon. Si la mise en œuvre de TabLayout
change, ce code peut ne pas fonctionner correctement ou même se bloquer.
Une autre façon de personnaliser TabLayout
consiste à y ajouter une vue personnalisée. Voici le grand exemple .
La méthode suivante changera la police dans ViewGroup
entière de manière récursive. J'ai choisi cette méthode parce que vous n'avez pas à vous soucier de la structure interne de TabLayout
. J'utilise Calligraphy library pour définir une police.
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);
}
}
}
Pour le support de conception 23.2.0, en utilisant setupWithViewPager, vous devrez déplacer le code de addTab (onglet) à addTab (onglet, boolean setSelected).
Eh bien, je l’ai trouvé simple en 23.4.0 sans utiliser de boucle. Remplacez simplement addTab (onglet @NonNull, boolean setSelected) comme suggéré par @ejw.
@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);
}
Et voici le 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" />
J'espère que ça pourrait aider :)
Vous pouvez l'utiliser, cela fonctionne pour moi.
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);
}
}
}
}
En tant que Andrei répondu, vous pouvez modifier la fontface en développant TabLayout class. Et comme Penzzz a dit, vous ne pouvez pas le faire avec addTab . Remplacer onLayout méthode comme suit:
@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);
}
}
}
}
La méthode onLayout doit être écrasée, car lorsque vous utilisez setupWithViewPager pour lier TabLayout avec ViewPager, vous devez définir le texte des onglets soit avec la méthode setText, soit dans PagerAdapter, puis, le cas échéant, avec la méthode onLayout. le ViewGroup parent (TabLayout) et c'est l'endroit idéal pour définir une fontface. (Changer un texte TextView provoque l'appel de la méthode onLayout de son parent - Un tabView a deux enfants, l'un est ImageView l'autre est TextView)
Une autre solution:
Premièrement, ces lignes de code:
if(fontFace == null){
fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.IranSans));
}
Dans la solution ci-dessus, doit être écrit en dehors de deux boucles.
Mais meilleure solution pour API> = 16 utilise Android: fontFamily :
Créez un répertoire de ressources Android named et copiez la police souhaitée dans le répertoire.
Ensuite, utilisez ces styles:
<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>
Pour utiliser la prise en charge des polices dans la fonction XML
sur les appareils exécutant Android 4.1
(niveau d'API 16) et supérieur, utilisez la bibliothèque de support technique 26+.
myfont.ttf
dans le dossier de polices nouvellement créé.Sur res/values/styles.xml
ajouter:
<style name="customfontstyle" parent="@Android:style/TextAppearance.Small">
<item name="Android:fontFamily">@font/myfont</item>
</style>
Dans le fichier de mise en page, ajoutez app: 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" />
Veuillez vous reporter à [polices en xml]. ( https://developer.Android.com/guide/topics/ui/look-and-feel/fonts-in-xml )
Ma méthode Resolve juste comme ça, change le texte de l'onglet spécifié,
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);
}
L'extension Kotlin qui a fonctionné pour moi:
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)
}
}
}
}
}
Mon 2p, Kotlin avec vérification des références, applicable partout car il va s'arrêter si quelque chose ne va pas.
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) }
}
}
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>
Et voici mon implémentation dans Kotlin qui autorise également le changement de police pour les onglets sélectionnés et non sélectionnés.
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()
}
}
}
dans 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>
Avec les fonctions d'extension kotlin, utilisez ceci:
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))
}
}
}
}