teclado - Cambiar la fuente del texto de la pestaña en el soporte de diseño de Android TabLayout
como cambiar la letra en las historias de whatsapp (17)
Bueno, lo encontré simple en 23.4.0 sin usar un bucle. Simplemente anule addTab (pestaña @NonNull Tab, boolean setSelected) como lo sugiere @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);
}
Y aquí está el 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" />
Espero que pueda ayudar :)
Estoy tratando de trabajar en el nuevo
TabLayout
de la biblioteca de diseño de Android.
Quiero cambiar el texto de la pestaña a
una fuente personalizada
.
Y traté de buscar algunos
TabLayout
relacionados con
TabLayout
, pero terminé
this
.
Guía cómo puedo cambiar las fuentes de texto de la pestaña.
Cambio
if (tabViewChild instanceof TextView) {
para
if (tabViewChild instanceof AppCompatTextView) {
para que funcione con android.support.design.widget.TabLayout (al menos desde com.android.support:design:23.2.0)
Como Andrei respondió, puede cambiar la fuente extendiendo la clase TabLayout . Y como dijo Penzzz , no puedes hacerlo con el método addTab . Anule el método onLayout como se indica a continuación:
@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);
}
}
}
}
Debe sobrescribir el método onLayout, porque, cuando usa el método setupWithViewPager para vincular el TabLayout con el ViewPager, debe establecer el texto de las pestañas con el método setText o en el Adaptador PagerApter después de eso y cuando esto sucede, se llama al método onLayout en el ViewGroup padre ( TabLayout) y ese es el lugar para poner la fuente de configuración. (Cambiar un texto TextView causa invocar el método Layout de su padre - Un tabView tiene dos hijos, uno es ImageView y otro es TextView)
Otra solución:
Primero, estas líneas de código:
if(fontFace == null){
fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.IranSans));
}
En la solución anterior, debe escribirse fuera de dos bucles.
Pero una mejor solución para API> = 16 es usar android: fontFamily :
Cree una fuente denominada Directorio de recursos de Android y copie la fuente deseada al directorio.
Luego use estos estilos:
<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>
Con las funciones de extensión de Kotlin, use esto:
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))
}
}
}
}
Cree su propio estilo personalizado y use el estilo
parent="@android:style/TextAppearance.Widget.TabWidget"
como
parent="@android:style/TextAppearance.Widget.TabWidget"
Y en el diseño de su pestaña use este estilo como
app:tabTextAppearance="@style/tab_text"
Ejemplo: Estilo:
<style name="tab_text" parent="@android:style/TextAppearance.Widget.TabWidget">
<item name="android:fontFamily">@font/poppins_regular</item>
</style>
Ejemplo: componente de diseño de pestaña:
<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" />
Cree un TextView desde Java Code o XML como este
<?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"
/>
Asegúrese de mantener la identificación como está aquí porque el TabLayout verifica esta ID si usa una vista de texto personalizada
Luego, desde el código, infle este diseño y configure el
Typeface
de
Typeface
personalizado en esa vista de texto y agregue esta vista personalizada a la pestaña
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);
}
El siguiente método cambiará la fuente en todo
ViewGroup
recursiva.
Elegí este método porque no tienes que preocuparte por la estructura interna de
TabLayout
.
Estoy usando la biblioteca de
Calligraphy
para configurar una fuente.
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);
}
}
}
Extensión de Kotlin que funcionó para mí:
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)
}
}
}
}
}
Gran respuesta de praveen Sharma.
Solo una pequeña adición: en lugar de usar
changeTabsFont()
todas partes donde necesite
TabLayout
, simplemente puede usar su propia
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);
}
}
}
}
Y una cosa más.
TabView
es un
LinearLayout
con
TextView
en
TextView
interior (también puede contener opcionalmente
ImageView
).
Para que pueda hacer el código aún más 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);
}
Pero no lo recomendaría de esta manera.
Si la implementación de
TabLayout
cambia, este código puede funcionar incorrectamente o incluso bloquearse.
Otra forma de personalizar
TabLayout
es agregarle una vista personalizada.
Aquí está el gran
example
.
Mi 2p, Kotlin con comprobación de referencias, aplicable en todas partes, ya que se detendrá si algo está mal
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) }
}
}
Mi método de resolución así, cambia el texto de la pestaña Especificado,
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);
}
Para el soporte de diseño 23.2.0, usando setupWithViewPager, tendrá que mover el código de addTab (pestaña Tab) a addTab (pestaña Tab, boolean setSelected).
Para usar el soporte de fuentes en la función
XML
en dispositivos con
Android 4.1
(nivel 16 de API) y superior, use la Biblioteca de soporte 26+.
- Haga clic derecho en la carpeta res
- Nuevo -> Directorio de recursos de Android-> seleccionar fuente -> Ok
-
Coloque su archivo
myfont.ttf
en la carpeta de fuentes recién creada
En
res/values/styles.xml
agregue:
<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
<item name="android:fontFamily">@font/myfont</item>
</style>
En el archivo de diseño, agregue la aplicación: 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" />
Consulte [fuentes en xml]. ( https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml )
Puedes usar esto, funciona para mí.
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);
}
}
}
}
Si está utilizando
TabLayout
y desea cambiar la fuente, debe agregar un nuevo bucle for a la solución anterior de esta manera:
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);
}
}
}
}
Consulte cambiar el estilo de fuente en las pestañas de la barra de acción con Sherlock
Y aquí está mi implementación en Kotlin que también permite cambiar la fuente para pestañas seleccionadas y no seleccionadas.
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()
}
}
}
en 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>
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>