2011-01-27 9 views

Odpowiedz

129

Cóż, nie mogłem wymyślić, jak to zrobić z dostępnymi klasami, więc rozszerzyłem TypefaceSpan na własną rękę i teraz działa dla mnie. Oto co zrobiłem:

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

Jakoś to nie będzie działać na guziki. Jakieś pomysły, dlaczego? – mikepenz

+0

@ notme co należy przekazać do rodziny zmiennych łańcuchowych w tym konstruktorze CustomTypefaceSpan (rodzina ciągów, typ kroju pisma) {} ??? – KJEjava48

82

Podczas notme ma zasadniczo prawo pomysł, rozwiązanie podane jest nieco hacky jako „rodzina” staje się zbędna. Jest również nieco niepoprawny, ponieważ TypefaceSpan jest jednym ze specjalnych zakresów, o których wie Android, i oczekuje pewnych zachowań w odniesieniu do interfejsu ParcelableSpan (którego podklasa notmy nie jest właściwa, ani nie jest możliwa do wdrożenia).

Prostsza i bardziej precyzyjne rozwiązanie byłoby:

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 Dziękuję! A [tutaj] (http://stackoverflow.com/a/10741161/89818) jest prawidłowym przykładem użycia. – caw

+0

@MarcoW i @Benjamin .... Benjamin mówi, że nie można używać "TypefaceSpan", ale Marco pokazuje przykład pracy, używając właśnie tego. Który jest właściwy? Benjamin, czy przetestowałeś swój przykład? –

+0

@JaysonMinard Myślę, że @MarcoW skomentował złą odpowiedź. Przypuszczam, że chciał skomentować odpowiedź @ notme, ponieważ użył jej w swojej klasie. Aby było jasne, nie mówię, że * nie można * podklasy 'TypefaceSpan'. Po prostu bardzo mocno sugeruję, że nie powinieneś tego robić. Takie postępowanie przełamuje zasadę podstawiania Liscova i jest wyjątkowo złą praktyką. Podklasowałeś klasę, która określa czcionkę poprzez "rodzinną" nazwę * i * jest działka; w ten sposób całkowicie nadpisałeś to zachowanie i sprawiłeś, że parametr "family" był mylący i bezcelowy, a 'Span' również * nie * jest paczkowany. –

-1

Próbowałem kilka podobnych rozwiązań, okazało się, że This jest proste i wykonalne. Wystarczy kliknąć element jest uchwyt jako kliknięcie przycisku zamiast onOptionsItemSelected. Dzięki!

Oto mój kod dla mojego projektu:

W moim 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 za przypomnienie, odpowiedź edytowana – rikayap

+0

Dziękuję panu. Przykro mi, że jestem szkodnikiem: P – Drew

+0

Nie dotyczy posta. – havchr

Powiązane problemy