Я не нашел способ сделать это. Возможно ли это?
Как я могу использовать 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);
}