कस्टम फ़ॉन्ट के साथ स्पैनेबल ऑब्जेक्ट फ़ॉन्ट कैसे सेट करें


80

मेरे पास Spannable ऑब्जेक्ट है जिसे मैं पहले से लोड किए गए कस्टम फ़ॉन्ट द्वारा इसका फ़ॉन्ट सेट करना चाहता हूं।

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.

संपादित करें:
मेरी समस्या यह है कि मैं पाठ दृश्य के लिए दो अलग-अलग कस्टम फ़ॉन्ट सेट करना चाहता हूं इसलिए मैं स्पैनबल के साथ काम कर रहा हूं



1
@BenjaminDobell एक प्रश्न उत्तर के डुप्लिकेट नहीं हो सकता है। अपने स्वयं के उत्तर से लिंक न करें।
चाड बिंघम

जवाबों:


217

यह एक देर से जवाब है लेकिन इस मुद्दे को हल करने में दूसरों की मदद करेगा।

निम्नलिखित कोड का उपयोग करें: (मैं बांग्ला और तमिल फ़ॉन्ट का उपयोग कर रहा हूँ)

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

परिणाम है:

यहाँ छवि विवरण दर्ज करें


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

संदर्भ


11
एक अच्छा - यद्यपि यदि आप इसे परिवार के साथ उपयोग करने जा रहे हैं "", तो क्यों नहीं निर्माण पैरामीटर को पारिवारिक पैरामीटर से पूरी तरह से हटा दें और बस सुपर ("") को कॉल करें;
एडम

@ इमरान-राणा मैं कैसे उपयोग कर सकता हूं CustomTypefaceSpan?
महदी पिशुगी

@ इमरान राणा, यह कस्टम वर्ग एक लिंट त्रुटि देता है। "यह वर्ग पार्सेबल को लागू करता है, लेकिन निर्माता क्षेत्र प्रदान नहीं करता है।"
क्रुप्स

@Krups हां, यह काम नहीं करने जा रहा है अगर CustomTypefaceSpan OS द्वारा पार्सल किया गया है और अनियंत्रित है।
alexbirkett

चेतावनी: यह वर्ग लागू Parcelableकरता है लेकिन एक CREATORक्षेत्र प्रदान नहीं करता है ।
मीर-इस्माइली

24

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

एंड्रॉइड फ्रेमवर्क की कक्षाओं के समान ही उपयोग करें:

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

यह उत्तर इमरान राणा के जवाब पर आधारित है लेकिन विस्तार नहीं करता है TypefaceSpanऔर फिर इसकी कार्यक्षमता को अक्षम करता है। सीधे CustomTypefaceSpanफैलता MetricAffectingSpanहै।

यह जवाब इमरान राणा के जवाब के साथ एक दोष साझा करता है। स्पान को पार्सल नहीं किया गया है। यानी अगर आप ऐसा करते हैं (कोटलिन):

    val parcel = Parcel.obtain()
    TextUtils.writeToParcel(spannableStringBuilder, parcel, 0)
    parcel.setDataPosition(0)
    val sequence = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel)
    parcel.recycle()

किसी भी CustomTypefaceSpanऑब्जेक्ट को सेट करने पर spannableStringBuilderमार्शल्ड और अनमैर्शल्ड नहीं किया जाएगा।


21

हमें CustomTypefaceSpan का उपयोग करने की आवश्यकता नहीं है। यहाँ 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);

3
StyleSpan को टाइपफेस सेट करने का इरादा नहीं है। जैसा कि डोक्यूमेटेशन में कहा गया है: स्पैन जो उस पाठ की शैली को सेट करने की अनुमति देता है जो इसके साथ जुड़ा हुआ है। संभावित शैलियाँ इस प्रकार हैं: टाइपफेस # नोर्मल, टाइपफेस # बोल्ड, टाइपफेस # आईटीएएलआईसी और टाइपफेस # बॉल्डिस्टिक। यह देखते हुए कि कोड बोल्ड को प्रभावित करेगा, टाइपफेस को प्रभावित नहीं करेगा
kza

14

यदि आप Roboto का उपयोग कर रहे हैं, तो आप कंस्ट्रक्टर में एक अलग TypefaceSpan सेट कर सकते हैं

TypefaceSpan typefaceSpan = new TypefaceSpan("sans-serif-medium");

textView.setSpan(typefaceSpan, indexStart, textLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

3

> = एपीआई 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 = string

2

कोटलिन में होगा:

पहला कदम , इस वर्ग को बनाएं

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

}

दूसरा कदम ,

    val prefixText = SpannableString("I read and accept ")
    val prefixTextLen = prefixText.length

    prefixText.setSpan(
        CustomTypefaceSpan("", ResourcesCompat.getFont(context, R.font.gotham_bold)!!),
        0,
        prefixTextLen,
        0
    )

1

Spannableअपना TextViewपहला और फिर सेट करने का प्रयास करें , अपने TextViewसाथ टाइपफेस को असाइन करने का प्रयास करें myTextView.setTypeface(tf);


आगे सेरकान के उत्तर के लिए, मैंने एक ब्लॉग प्रविष्टि लिखी है, जिसमें बताया गया है कि कैसे ब्लॉग पर spans का उपयोग करना है ।stylingandroid.com / archives / 177 । यह विशेष रूप से सेटिंग टाइपफ़्स को कवर नहीं करता है, यही कारण है कि मैंने इसे उत्तर के रूप में पोस्ट नहीं किया है, लेकिन यह सामान्य रूप से स्पैन के साथ कुछ सामान्य नुकसानों को कवर करता है।
मार्क एलिसन

लेकिन यह सिर्फ पूरे TextView पर टाइपफेस सेट करता है? यह एक अवधि नहीं है।
एलेक्सब्रिकेट

0

यदि आप android KTX का उपयोग कर रहे हैं buildSpannable{...} ,

मैं यह सलाह देता हूं।

inline fun SpannableStringBuilder.font(typeface: Typeface? = null, builderAction: SpannableStringBuilder.() -> Unit) =
    inSpans(StyleSpan(typeface?.style ?: Typeface.DEFAULT.style), builderAction = builderAction)

प्रयोग

binding.title.text = buildSpannedString {
    color(getColor(R.color.main_mint)) {
        font(getFont(R.font.notosans_medium)) {
            append("colored and typefaced")
        }
    }
}

-1

यहाँ एक उदाहरण है जहाँ, str आपका पूरा स्ट्रिंग है और boldString वह हिस्सा है जिसे आपको बोल्ड बनाने की आवश्यकता है।

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;
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.