2011-01-27 7 views

risposta

129

Beh, non riuscivo a capire come farlo con le classi disponibili, quindi ho ampliato il TypefaceSpan da solo e ora funziona per me. Ecco quello che ho fatto:

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

In qualche modo questo non funzionerà sui pulsanti. Qualche idea, perché? – mikepenz

+0

@notme cosa devo passare alla famiglia di variabili stringa in questo costruttore CustomTypefaceSpan (famiglia di stringhe, tipo di carattere tipografico) {} ??? – KJEjava48

82

Mentre notme ha essenzialmente l'idea giusta, la soluzione data è un po 'hacky come "famiglia" diventa ridondante. È anche un po 'scorretto perché TypefaceSpan è uno degli span speciali che Android conosce e si aspetta determinati comportamenti rispetto all'interfaccia ParcelableSpan (che la sottoclasse di notme non è propriamente, né è possibile implementare).

Una soluzione più semplice e più accurata sarebbe:

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 Grazie! E [qui] (http://stackoverflow.com/a/10741161/89818) è un esempio di utilizzo corretto. – caw

+0

@MarcoW e @Benjamin .... Benjamin dice che non puoi usare 'TypefaceSpan', ma Marco mostra un esempio funzionante usando proprio questo. Qual è quello giusto? Benjamin hai messo alla prova il tuo esempio? –

+0

@JaysonMinard Penso che @MarcoW abbia commentato la risposta sbagliata. Suppongo che intendesse commentare la risposta di @ notme, dato che è la sua classe che ha usato. Per essere chiari, non sto dicendo che * non può * sottoclasse 'TypefaceSpan'. Sto solo suggerendo fortemente __non dovresti__. Farlo interrompe il principio di sostituzione di Liscov ed è una pratica estremamente negativa. Hai sottoclassificato una classe che specifica il carattere tramite un nome 'family' * e * è parcelable; hai quindi totalmente sovrascritto quel comportamento e reso il parametro 'family' confuso e inutile, e' Span' è anche * non * parcelable. –

-1

Ho provato diverse soluzioni simili, ha scoperto che This è semplice e praticabile. Solo che l'elemento click è gestito come un clic del pulsante anziché onOptionsItemSelected. Grazie!

Ecco il mio codice per il mio progetto:

Nel mio 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> 

In 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); 
} 
+0

Thx per ricordare, risposta modificata – rikayap

+0

Grazie signore. Mi spiace di essere un parassita: P – Drew

+0

Non pertinente alla domanda postata. – havchr

Problemi correlati