由于这两个答案MJM
和TheMatrix
实际上是相同的(但过于复杂的我),两者都在同一时间回答,我不能只选择其中的一个,所以我理所当然+1每个,要求他们把它缩短但支持XML标记,以便更轻松地处理字符串文件.
目前,这是如何为TextView中的部分文本设置自定义字体的更短版本:
class CustomTypefaceSpan(private val typeface: Typeface?) : MetricAffectingSpan() { override fun updateDrawState(paint: TextPaint) { paint.typeface=typeface } override fun updateMeasureState(paint: TextPaint) { paint.typeface=typeface } }
样品用法:
val text = "Hello world" val index = text.indexOf(' ') val spannable = SpannableStringBuilder(text) spannable.setSpan(CustomTypefaceSpan(ResourcesCompat.getFont(this, R.font.lato_light)), 0, index, Spanned.SPAN_EXCLUSIVE_INCLUSIVE) spannable.setSpan(CustomTypefaceSpan(ResourcesCompat.getFont(this, R.font.lato_bold)), index, text.length, Spanned.SPAN_EXCLUSIVE_INCLUSIVE) textView.text = spannable
编辑:似乎谷歌提供了一个关于此的视频,在这里:
class CustomTypefaceSpan(val font: Typeface?) : MetricAffectingSpan() { override fun updateMeasureState(textPaint: TextPaint) = update(textPaint) override fun updateDrawState(textPaint: TextPaint?) = update(textPaint) private fun update(tp: TextPaint?) { tp.apply { val old = this!!.typeface val oldStyle = old?.style ?: 0 val fOnt= Typeface.create(font, oldStyle) typeface = font } } }
并且在视频中也讨论了在strings.xml中处理它的解决方案,这里使用注释而不是新的HTML标记.例:
strings.xml中
Hello world
MainActivity.kt
val titleText = getText(R.string.title) as SpannedString val spannable = SpannableStringBuilder(titleText) val annotatiOns= titleText.getSpans(0, titleText.length, android.text.Annotation::class.java) for (annotation in annotations) { if(annotation.key=="font"){ val fOntName=annotation.value val typeface= ResourcesCompat.getFont(this@MainActivity,resources.getIdentifier(fontName,"font",packageName)) spannable.setSpan(CustomTypefaceSpan(typeface),spannable.getSpanStart(annotation),spannable.getSpanEnd(annotation), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) } } textView.text = spannable
结果如下:
我仍然很确定可以使用fromHtml,但它可能不值得.
我也想知道如果我们想要使用基本HTML标签和我们为字体设置的cusomzied,如果我们确实annotation
在那里使用,应该怎么做.
由于这两个答案MJM
和TheMatrix
实际上是相同的(但过于复杂的我),两者都在同一时间回答,我不能只选择其中的一个,所以我理所当然+1每个,要求他们把它缩短但支持XML标记,以便更轻松地处理字符串文件.
目前,这是如何为TextView中的部分文本设置自定义字体的更短版本:
class CustomTypefaceSpan(private val typeface: Typeface?) : MetricAffectingSpan() { override fun updateDrawState(paint: TextPaint) { paint.typeface=typeface } override fun updateMeasureState(paint: TextPaint) { paint.typeface=typeface } }
样品用法:
val text = "Hello world" val index = text.indexOf(' ') val spannable = SpannableStringBuilder(text) spannable.setSpan(CustomTypefaceSpan(ResourcesCompat.getFont(this, R.font.lato_light)), 0, index, Spanned.SPAN_EXCLUSIVE_INCLUSIVE) spannable.setSpan(CustomTypefaceSpan(ResourcesCompat.getFont(this, R.font.lato_bold)), index, text.length, Spanned.SPAN_EXCLUSIVE_INCLUSIVE) textView.text = spannable
编辑:似乎谷歌提供了一个关于此的视频,在这里:
class CustomTypefaceSpan(val font: Typeface?) : MetricAffectingSpan() { override fun updateMeasureState(textPaint: TextPaint) = update(textPaint) override fun updateDrawState(textPaint: TextPaint?) = update(textPaint) private fun update(tp: TextPaint?) { tp.apply { val old = this!!.typeface val oldStyle = old?.style ?: 0 val fOnt= Typeface.create(font, oldStyle) typeface = font } } }
并且在视频中也讨论了在strings.xml中处理它的解决方案,这里使用注释而不是新的HTML标记.例:
strings.xml中
Hello world
MainActivity.kt
val titleText = getText(R.string.title) as SpannedString val spannable = SpannableStringBuilder(titleText) val annotatiOns= titleText.getSpans(0, titleText.length, android.text.Annotation::class.java) for (annotation in annotations) { if(annotation.key=="font"){ val fOntName=annotation.value val typeface= ResourcesCompat.getFont(this@MainActivity,resources.getIdentifier(fontName,"font",packageName)) spannable.setSpan(CustomTypefaceSpan(typeface),spannable.getSpanStart(annotation),spannable.getSpanEnd(annotation), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) } } textView.text = spannable
结果如下:
我仍然很确定可以使用fromHtml,但它可能不值得.
我也想知道如果我们想要使用基本HTML标签和我们为字体设置的cusomzied,如果我们确实annotation
在那里使用,应该怎么做.
自定义类别适用fonrFamilySpan
public class MultipleFamilyTypeface extends TypefaceSpan { private final Typeface typeFace; public MultipleFamilyTypeface(String family, Typeface type) { super(family); typeFace = type; } @Override public void updateDrawState(TextPaint ds) { applyTypeFace(ds, typeFace); } @Override public void updateMeasureState(TextPaint paint) { applyTypeFace(paint, typeFace); } private static void applyTypeFace(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); } }
应用字体
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String firstWord = "Hello "; String secOndWord= "Word "; String thirdWord = "Normal "; TextView textViewTest = findViewById(R.id.textViewTest); Spannable spannable = new SpannableString(firstWord + secondWord + thirdWord); Typeface CUSTOM_TYPEFACE = ResourcesCompat.getFont(this, R.font.akronim); Typeface SECOND_CUSTOM_TYPEFACE = ResourcesCompat.getFont(this, R.font.baloo_thambi); spannable.setSpan(new MultipleFamilyTypeface("akronim", CUSTOM_TYPEFACE), 0, firstWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); spannable.setSpan(new MultipleFamilyTypeface("baloo_thambi", SECOND_CUSTOM_TYPEFACE), firstWord.length(), firstWord.length() + secondWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); textViewTest.setText(spannable); } }
输出
自定义标签的编辑方法二
加入implementation 'org.jsoup:jsoup:1.11.3'
gradle
ListmyCustomTag = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textViewTest = findViewById(R.id.textViewTest); // mention list custom tag that you used myCustomTag.add("akronim"); myCustomTag.add("baloo_thambi"); myCustomTag.add("xyz"); String html = " Hello " + "Word " + " Normal " + "testing " + "Styles "; textViewTest.setText(processToFontStyle(html)); } public Spannable processToFontStyle(String text) { Document doc = Jsoup.parse(text); Elements tags = doc.getAllElements(); String cleanText = doc.text(); Log.d("ClearTextTag", "Text " + cleanText); Spannable spannable = new SpannableString(cleanText); ListtagsFromString = new ArrayList<>(); List startTextPosition = new ArrayList<>(); List endTextPosition = new ArrayList<>(); for (Element tag : tags) { String nodeText = tag.text(); if (myCustomTag.contains(tag.tagName())) { int startingIndex = cleanText.indexOf(nodeText); tagsFromString.add(tag.tagName()); startTextPosition.add(startingIndex); endTextPosition.add(startingIndex + nodeText.length()); } } Typeface CUSTOM_TYPEFACE = ResourcesCompat.getFont(this, R.font.akronim); Typeface SECOND_CUSTOM_TYPEFACE = ResourcesCompat.getFont(this, R.font.baloo_thambi); Typeface XYZ_CUSTOM_TYPEFACE = ResourcesCompat.getFont(this, R.font.architects_daughter); for (int i = 0; i 输出