Я не нашел способ сделать это. Возможно ли это?
Как я могу использовать TypefaceSpan или StyleSpan с пользовательским шрифтом?
Ответ 1
Ну, я не мог понять, как это сделать с доступными классами, поэтому я расширил 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);
    }
}
Ответ 2
В то время как notme имеет, по сути, правильную идею, данное решение немного хакерское, поскольку "семья" становится излишней. Это также немного некорректно, потому что TypefaceSpan является одним из особых условий, о которых знает Android и ожидает определенного поведения в отношении интерфейса ParcelableSpan (который не соответствует подклассу, и не может его реализовать).
Более простым и точным решением было бы следующее:
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);
    }
}
Ответ 3
Я попробовал несколько аналогичных решений, обнаружил, что This прост и работоспособен. Просто, чтобы щелчок элемента был дескриптором как щелчок кнопки, а не 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);
}
