Tengo un objeto Spannable que quiero configurar su fuente mediante una fuente personalizada que he cargado antes.
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/font_Name.ttf");
Spannable span1 = /*Spannable Item*/;
/// I want to set span1 to have tf font face???
/// Here where I want help.
EDITAR:
Mi problema es que quiero configurar dos fuentes personalizadas diferentes para la vista de texto, así que estoy trabajando con Spannable
android
android-fonts
spannable
Mohamedghonemi
fuente
fuente

Respuestas:
Esta es una respuesta tardía, pero ayudará a otros a resolver el problema.
Use el siguiente código: (estoy usando la fuente bengalí y tamil)
TextView txt = (TextView) findViewById(R.id.custom_fonts); txt.setTextSize(30); Typeface font = Typeface.createFromAsset(getAssets(), "Akshar.ttf"); Typeface font2 = Typeface.createFromAsset(getAssets(), "bangla.ttf"); SpannableStringBuilder SS = new SpannableStringBuilder("আমারநல்வரவு"); SS.setSpan (new CustomTypefaceSpan("", font2), 0, 4,Spanned.SPAN_EXCLUSIVE_INCLUSIVE); SS.setSpan (new CustomTypefaceSpan("", font), 4, 11,Spanned.SPAN_EXCLUSIVE_INCLUSIVE); txt.setText(SS);El resultado es:
Clase CustomTypefaceSpan:
package my.app; import android.graphics.Paint; import android.graphics.Typeface; import android.text.TextPaint; import android.text.style.TypefaceSpan; public class CustomTypefaceSpan extends TypefaceSpan { private final Typeface newType; public CustomTypefaceSpan(String family, Typeface type) { super(family); newType = type; } @Override public void updateDrawState(TextPaint ds) { applyCustomTypeFace(ds, newType); } @Override public void updateMeasureState(TextPaint paint) { applyCustomTypeFace(paint, newType); } private static void applyCustomTypeFace(Paint paint, Typeface tf) { int oldStyle; Typeface old = paint.getTypeface(); if (old == null) { oldStyle = 0; } else { oldStyle = old.getStyle(); } int fake = oldStyle & ~tf.getStyle(); if ((fake & Typeface.BOLD) != 0) { paint.setFakeBoldText(true); } if ((fake & Typeface.ITALIC) != 0) { paint.setTextSkewX(-0.25f); } paint.setTypeface(tf); } }Referencia
fuente
CustomTypefaceSpan?Parcelablepero no proporciona unCREATORcampo.Cree una clase CustomTypefaceSpan:
import android.graphics.Paint; import android.graphics.Typeface; import android.text.TextPaint; import android.text.style.MetricAffectingSpan; public class CustomTypefaceSpan extends MetricAffectingSpan { private final Typeface typeface; public CustomTypefaceSpan(Typeface typeface) { this.typeface = typeface; } @Override public void updateDrawState(TextPaint ds) { applyCustomTypeFace(ds, typeface); } @Override public void updateMeasureState(TextPaint paint) { applyCustomTypeFace(paint, typeface); } private static void applyCustomTypeFace(Paint paint, Typeface tf) { paint.setTypeface(tf); } }Úselo de la misma manera que el marco de Android abarca clases:
TextView textView = (TextView) findViewById(R.id.custom_fonts); Typeface font = Typeface.createFromAsset(getAssets(), "Akshar.ttf"); Typeface font2 = Typeface.createFromAsset(getAssets(), "bangla.ttf"); SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder("আমারநல்வரவு"); spannableStringBuilder.setSpan (new CustomTypefaceSpan(font2), 0, 4,Spanned.SPAN_EXCLUSIVE_INCLUSIVE); spannableStringBuilder.setSpan (new CustomTypefaceSpan(font), 4, 11,Spanned.SPAN_EXCLUSIVE_INCLUSIVE); textView.setText(spannableStringBuilder);Esta respuesta se basa en la respuesta de Imran Rana, pero no se extiende
TypefaceSpany luego desactiva su funcionalidad.CustomTypefaceSpanse extiendeMetricAffectingSpandirectamente.Esta respuesta comparte un defecto con la respuesta de Imran Rana. El tramo no está parcelado. Es decir, si haces esto (kotlin):
val parcel = Parcel.obtain() TextUtils.writeToParcel(spannableStringBuilder, parcel, 0) parcel.setDataPosition(0) val sequence = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel) parcel.recycle()Cualquier
CustomTypefaceSpanobjeto colocado enspannableStringBuilderno será ordenado ni desordenado.fuente
No necesitamos utilizar CustomTypefaceSpan. Aquí está la solución con StyleSpan .
/** * setCustomFontTypeSpan * @param context * @param source * @param startIndex * @param endIndex * @param font * @return */ public static SpannableString setCustomFontTypeSpan(Context context, String source, int startIndex, int endIndex, int font) { final SpannableString spannableString = new SpannableString(source); Typeface typeface = ResourcesCompat.getFont(context, font); spannableString.setSpan(new StyleSpan(typeface.getStyle()), startIndex,endIndex,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return spannableString; } String source = "Hello world"; SpannableString string = setCustomFontTypeSpan(context, source, 6, source.length(), R.font.open_sans_bold); textView.setText(string);fuente
Si está utilizando Roboto, puede establecer un TypefaceSpan diferente en el constructor
TypefaceSpan typefaceSpan = new TypefaceSpan("sans-serif-medium"); textView.setSpan(typefaceSpan, indexStart, textLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);fuente
Respuesta más nueva y sencilla para> = API 28
val myTypeface = Typeface.create(ResourcesCompat.getFont(context, R.font.acme), Typeface.NORMAL) val string = SpannableString("Text with typeface span.") string.setSpan(TypefaceSpan(myTypeface), 10, 18, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) string.setSpan(TypefaceSpan("monospace"), 19, 22, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) textView.text = stringfuente
En kotlin estaría:
Primer paso , crea esta clase
class CustomTypefaceSpan(family: String?, private val newType: Typeface) : TypefaceSpan(family) { override fun updateDrawState(ds: TextPaint) { applyCustomTypeFace(ds, newType) } override fun updateMeasureState(paint: TextPaint) { applyCustomTypeFace(paint, newType) } companion object { private fun applyCustomTypeFace(paint: Paint, tf: Typeface) { val oldStyle: Int val old = paint.typeface oldStyle = old?.style ?: 0 val fake = oldStyle and tf.style.inv() if (fake and Typeface.BOLD != 0) { paint.isFakeBoldText = true } if (fake and Typeface.ITALIC != 0) { paint.textSkewX = -0.25f } paint.typeface = tf } } }Segundo paso ,
val prefixText = SpannableString("I read and accept ") val prefixTextLen = prefixText.length prefixText.setSpan( CustomTypefaceSpan("", ResourcesCompat.getFont(context, R.font.gotham_bold)!!), 0, prefixTextLen, 0 )fuente
Trate de establecer su
Spannableen suTextViewprimero y luego, intente asignar el tipo de letra a suTextViewconmyTextView.setTypeface(tf);fuente
Si está utilizando Android KTX
buildSpannable{...},Recomiendo este.
inline fun SpannableStringBuilder.font(typeface: Typeface? = null, builderAction: SpannableStringBuilder.() -> Unit) = inSpans(StyleSpan(typeface?.style ?: Typeface.DEFAULT.style), builderAction = builderAction)Uso
binding.title.text = buildSpannedString { color(getColor(R.color.main_mint)) { font(getFont(R.font.notosans_medium)) { append("colored and typefaced") } } }fuente
Aquí hay un ejemplo en el que str es su cadena completa y boldString es la parte que necesita poner en negrita.
public static SpannableString getTextStyleSpan(String str, String boldString) { SpannableString formated = new SpannableString(str); int start1 = str.indexOf(boldString); int end1 = start1 + colorString1.length(); formated.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), start1, end1, Spannable.SPAN_INCLUSIVE_INCLUSIVE); return formated; }fuente