2011-01-27 19 views

回答

129

嗯,我无法弄清楚如何用可用的类来做到这一点,所以我自己扩展了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

不知怎的,这不会对按钮的作用。任何想法为什么? – mikepenz 2014-11-02 10:25:54

+0

@notme我应该传递给此构造函数中的字符串变量族CustomTypefaceSpan(String family,Typeface type){} ??? – KJEjava48 2017-03-08 11:27:10

82

尽管notme基本上是正确的想法,但给出的解决方案有点怪异,因为“family”变得多余。它也有点不正确,因为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); 
    } 
} 
+1

+1谢谢!和[这里](http://stackoverflow.com/a/10741161/89818)是一个正确的用法示例。 – caw 2014-07-24 04:37:02

-1

我尝试了好几种类似的解决方案,发现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> 

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