2011-01-27 28 views

cevap

129

Peki, mevcut sınıflar ile nasıl yapılacağını anlayamadım, böylece TypefaceSpan'u kendi başıma geliştirdim, şimdi benim için çalışıyor. İşte ne yaptım: notme esasen doğru karar verdi iken

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

Her nasılsa bu düğmeler çalışmaz

İşte benim proje için benim kodudur. Herhangi bir fikir neden? – mikepenz

+0

@notme Bu kurucu CustomTypefaceSpan (String ailesi, Yazı tipi türü) dizgisi değişken ailesine ne geçmeliyim {} ??? – KJEjava48

82

, verilen çözüm "ailesi" olarak biraz hacky olan gereksiz hale gelir. Aynı zamanda biraz yanlıştır, çünkü TypefaceSpan, Android'in bildiği ve ParcelableSpan arabirimine göre belirli davranışları beklediği (notme'nin alt sınıfının düzgün bir şekilde uygulanmadığı veya uygulanmasının mümkün olmadığı) özel açıklardan biridir.

daha basit ve daha doğru bir çözüm olacaktır: Ben birkaç benzer çözümler denedi

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 Teşekkürler! Ve [burada] (http://stackoverflow.com/a/10741161/89818) uygun kullanım örneğidir. – caw

+0

@MarcoW ve @Benjamin .... Benjamin, 'TypefaceSpan' kullanamayacağınızı söylüyor ancak Marco sadece bunu kullanarak çalışan bir örnek gösteriyor. Hangisi doğru olanı? Benjamin örneğini test ettin mi? –

+0

@JaysonMinard Sanırım @MarcoW yanlış cevabı yorumladı. Sanırım kullandığı sınıf olduğu gibi @ notme'nin cevabı üzerine yorum yapmak istedi. Açık olmak gerekirse, ben * alt sınıf "TypefaceSpan" diyemezsiniz. Ben sadece çok kuvvetli bir şekilde önerdim. Bunu yapmak Liscov'un yerine geçme prensibini kırar ve son derece kötü bir uygulamadır. Yazı tipini bir 'aile' adıyla belirten bir sınıfın alt sınıfını oluşturdunuz * ve * ayrıştırılabilir; Daha sonra bu davranışların tamamen üzerine yazıldınız ve “aile” parametresini kafa karıştırıcı ve anlamsız hale getirdiniz ve “Span” da * parcelable değil. –

-1

, This basit ve uygulanabilir olduğunu gördük. Sadece öğenin tıklanması, onOptionsItemSelected yerine düğme tıklaması olarak ele alınır. Teşekkürler! Benim menu_main.xml olarak

: My MainActivity.java olarak

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

:

@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

Hatırlatmak için teşekkürler, cevap düzenlenir – rikayap

+0

Teşekkür ederim bayım. Zararlı olduğum için üzgünüm: P – Drew

+0

Gönderilen soruyla ilgisi yok. – havchr

İlgili konular