Как я могу использовать TypefaceSpan или StyleSpan с пользовательским шрифтом?

Я не нашел способ сделать это. Является ли это возможным?

Ну, я не мог понять, как это сделать с доступными классами, поэтому я расширил TypefaceSpan самостоятельно, теперь это работает для меня. Вот что я сделал:

 package de.myproject.text.style; 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); } } 

В то время как notme имеет, по сути, правильную идею, данное решение немного хакерское, поскольку «семья» становится излишней. Это также немного некорректно, потому что TypefaceSpan является одним из специальных диапазонов, о которых знает Android и ожидает определенного поведения в отношении интерфейса ParcelableSpan (какой подкласс notme не работает должным образом и не реализуется).

Более простым и точным решением было бы следующее:

 public class CustomTypefaceSpan extends MetricAffectingSpan { private final Typeface typeface; public CustomTypefaceSpan(final Typeface typeface) { this.typeface = typeface; } @Override public void updateDrawState(final TextPaint drawState) { apply(drawState); } @Override public void updateMeasureState(final TextPaint paint) { apply(paint); } private void apply(final Paint paint) { final Typeface oldTypeface = paint.getTypeface(); final int oldStyle = oldTypeface != null ? oldTypeface.getStyle() : 0; final int fakeStyle = oldStyle & ~typeface.getStyle(); if ((fakeStyle & Typeface.BOLD) != 0) { paint.setFakeBoldText(true); } if ((fakeStyle & Typeface.ITALIC) != 0) { paint.setTextSkewX(-0.25f); } paint.setTypeface(typeface); } } 

Я попробовал несколько аналогичных решений, обнаружил, что это просто и эффективно. Просто щелчок элемента является дескриптором как щелчок кнопки, а не onOptionsItemSelected. Благодаря!

Вот мой код для моего проекта:

В моем menu_main.xml:

 <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> <item android:id="@+id/action_friends" android:orderInCategory="100" android:title="@string/hello_world" app:actionViewClass="android.widget.Button" app:showAsAction="always" /> <item android:id="@+id/action_settings" android:orderInCategory="100" android:title="@string/action_settings" app:showAsAction="never" /> </menu> 

В My MainActivity.java:

 @Override public boolean onCreateOptionsMenu(Menu menu) { //Use custom menu MenuInflater inflater = getMenuInflater(); //Inflate the custom menu inflater.inflate(R.menu.menu_main, menu); //reference to the item of the menu MenuItem i=menu.findItem(R.id.action_friends); Button itemuser =(Button) i.getActionView(); if(itemuser!=null){ // Create Typeface object to use unicode font in assets folder Typeface a = Typeface.createFromAsset(getApplicationContext(), "fontawesome-webfont.ttf"); // Set unicode font to menu item itemuser.setTypeface(a); itemuser.setText(getString(R.string.fa_users)); // Set item text and color itemuser.setTextColor(Color.BLACK); // Make item background transparent itemuser.setBackgroundColor(Color.TRANSPARENT); itemuser.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { //set action when clicked } }); } return super.onCreateOptionsMenu(menu); }