Android: Çalışma zamanı yerine tüm uygulama için özel yazı tipleri ayarlamak istiyorum


100

Uygulamanın her kontrolünde herhangi bir özel yazı tipi ayarlamak mümkün mü? Ve mutlaka çalışma zamanı değil mi? (yani mümkünse xml'den veya JAVA dosyasındaki tüm uygulama için yalnızca bir kez)

Bu koddan bir kontrol için yazı tipini ayarlayabilirim.

public static void setFont(TextView textView) {
    Typeface tf = Typeface.createFromAsset(textView.getContext()
            .getAssets(), "fonts/BPreplay.otf");

    textView.setTypeface(tf);

}

Ve bu kodla ilgili sorun, her kontrol için çağrılması gerektiğidir. Ve bunu veya benzer bir yöntemi bir kez çağırmak veya mümkünse özelliği xml'de ayarlamak istiyorum. Mümkün mü?


6
TextView'i genişleterek ve kurucuda fontu ayarlayarak özel bir kontrol yazabilirsiniz, bu durumda bu kontrolü metin görünümünüzün uygulama içinde kullanabilirsiniz. ayrıca bellek tasarrufu yapmak için, statik yazı tipi kullanarak kaynakların yüklenmesini önleyebilirsiniz.
Varun

@Varun: peki bu fikir zaman kazandırabilir, ancak her kontrolü ayarlamam gerekiyor ve her biri için özel kontrol yazmak bir yazı tipi çalışma zamanı belirlemekten daha uzun bir yol olacak, ne düşünüyorsunuz? (Ancak özel kontrol yazmak için +1)
Prasham

TextView'ı genişleten yalnızca bir özel denetim yazmak isteyebilirsiniz ve tek değişiklik yazı tipini ayarlamak olacaktır. Mizanpaj dosyalarınızda cusotm kontrolünü kullanarak, bunu her metin görünümü için her zaman manuel olarak yapmanız gerekmez ve u, istediğiniz fontu kullandığınızdan emin olabilirsiniz.
Varun

Ayrı ayrı VIEWbir custom text viewve bir yazmak yerine bir adet yazmaya ne dersiniz custom button view? Benim ihtiyacım her kontrol için ve metin görünümü sadece bir örnekti. Üzgünüm, bundan bahsetmeyi unuttum .. :-(
Prasham

1
Satckoverflow sorusuna bir göz atın stackoverflow.com/questions/2711858/… size yardımcı olur.
Ashwini

Yanıtlar:


123

DÜZENLEME : Uzun zaman oldu ve bunu yapmanın en iyi yolu olduğunu düşündüğüm şeyi eklemek istiyorum ve XML aracılığıyla daha az değil!

Öncelikle, özelleştirmek istediğiniz Görünümü geçersiz kılan yeni bir sınıf oluşturmak isteyeceksiniz. (ör Button. özel yazı tipine sahip bir Düğme mi istiyorsunuz? Genişletin ). Bir örnek verelim:

public class CustomButton extends Button {
    private final static int ROBOTO = 0;
    private final static int ROBOTO_CONDENSED = 1;

    public CustomButton(Context context) {
        super(context);
    }

    public CustomButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        parseAttributes(context, attrs); //I'll explain this method later
    }

    public CustomButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        parseAttributes(context, attrs);
    }
}

Şimdi, yoksa, altına bir XML belgesi res/values/attrs.xmlekleyin ve şunu ekleyin:

<resources>
    <!-- Define the values for the attribute -->
    <attr name="typeface" format="enum">
        <enum name="roboto" value="0"/>
        <enum name="robotoCondensed" value="1"/>
    </attr>

    <!-- Tell Android that the class "CustomButton" can be styled, 
         and which attributes it supports -->
    <declare-styleable name="CustomButton">
        <attr name="typeface"/>
    </declare-styleable>
</resources>

Tamam, öyleyse bunun dışında, parseAttributes()yönteme daha önce geri dönelim :

private void parseAttributes(Context context, AttributeSet attrs) {
    TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.CustomButton);

    //The value 0 is a default, but shouldn't ever be used since the attr is an enum
    int typeface = values.getInt(R.styleable.CustomButton_typeface, 0);

    switch(typeface) {
        case ROBOTO: default:
            //You can instantiate your typeface anywhere, I would suggest as a 
            //singleton somewhere to avoid unnecessary copies
            setTypeface(roboto); 
            break;
        case ROBOTO_CONDENSED:
            setTypeface(robotoCondensed);
            break;
    }

    values.recycle();
}

Artık hazırsınız. Herhangi bir şey için daha fazla öznitelik ekleyebilirsiniz (typefaceStyle için başka bir tane ekleyebilirsiniz - kalın, italik, vb.) Ama şimdi nasıl kullanılacağını görelim:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/com.yourpackage.name"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.yourpackage.name.CustomButton
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click Me!"
        custom:typeface="roboto" />

</LinearLayout>

xmlns:customSatır gerçekten herhangi bir şey olabilir, ama kongre yukarıda gösterilen şeydir. Önemli olan benzersiz olmasıdır ve bu yüzden paket adı kullanılır. Artık custom:özellikleriniz için android:ön eki ve android özellikleri için ön eki kullanırsınız.

Son bir şey: Bir stil (bu kullanmak istiyorsanız res/values/styles.xml), sen gerektiğini değil eklemek xmlns:customhattı. Önek olmadan özniteliğin adına referans verin:

<style name="MyStyle>
    <item name="typeface">roboto</item>
</style>

                               (PREVIOUS ANSWER)

Android'de özel bir yazı tipi kullanma

Bu yardımcı olmalı. Temel olarak, bunu XML'de yapmanın bir yolu yok ve anlayabildiğim kadarıyla bunu kodda yapmanın daha kolay bir yolu yok. Her zaman bir setLayoutFont () yöntemine sahip olabilirsiniz, bu yöntem bir kez yazı tipini oluşturur ve ardından her biri için setTypeface () öğesini çalıştırır. Bir düzene her yeni öğe eklediğinizde sadece güncellemeniz gerekir. Aşağıdaki gibi bir şey:

public void setLayoutFont() {
    Typeface tf = Typeface.createFromAsset(
        getBaseContext().getAssets(), "fonts/BPreplay.otf");
    TextView tv1 = (TextView)findViewById(R.id.tv1);
    tv1.setTypeface(tf);

    TextView tv2 = (TextView)findViewById(R.id.tv2);
    tv2.setTypeface(tf);

    TextView tv3 = (TextView)findViewById(R.id.tv3);
    tv3.setTypeface(tf);
}

DÜZENLEME : Ben de böyle bir şeyi kendim uygulamaya başladım ve bunu nasıl yaptığım şöyle bir işlev yapıyordu:

public static void setLayoutFont(Typeface tf, TextView...params) {
    for (TextView tv : params) {
        tv.setTypeface(tf);
    }
}

Ardından, onCreate () 'deki bu yöntemi kullanın ve güncellemek istediğiniz tüm Metin Görünümlerini iletin:

Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
//find views by id...
setLayoutFont(tf, tv1, tv2, tv3, tv4, tv5);

9/5/12 DÜZENLE:

Bu hala görüş ve oy aldığından, çok daha iyi ve daha eksiksiz bir yöntem eklemek istiyorum:

Typeface mFont = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
ViewGroup root = (ViewGroup)findViewById(R.id.myrootlayout);
setFont(root, mFont);

/*
 * Sets the font on all TextViews in the ViewGroup. Searches
 * recursively for all inner ViewGroups as well. Just add a
 * check for any other views you want to set as well (EditText,
 * etc.)
 */
public void setFont(ViewGroup group, Typeface font) {
    int count = group.getChildCount();
    View v;
    for(int i = 0; i < count; i++) {
        v = group.getChildAt(i);
        if(v instanceof TextView || v instanceof Button /*etc.*/)
            ((TextView)v).setTypeface(font);
        else if(v instanceof ViewGroup)
            setFont((ViewGroup)v, font);
    }
}

Bunu mizanpajınızın kök dizininden geçirirseniz, o mizanpaj içinde tekrar tekrar kontrol eder TextViewveya Buttongörüntüler (veya bu if ifadesine eklediğiniz diğerlerini) ve kimlik ile belirtmenize gerek kalmadan yazı tipini ayarlar. Elbette bu, yazı tipini her görünüme ayarlamak istediğinizi varsayar .


1
Yöntemi tüm uygulama için fabrika yöntemi olarak kullanmam ve kodunuzun bir etkinlik için yazılmış gibi görünmesi dışında kodunuzda ve kodumda herhangi bir fark görmüyorum. Not: Sadece yazı tipini değiştirmek için salt okunur bir textView için bir nesne daha eklemek gerçekten garip. Konu Dışı: Android, varlıklar klasöründen bir yazı tipini almak ve tasarım saatini değiştirebilmek için R'ye dahil edilmek üzere gerçekten bir mekanizma
sunmalıdır

1
Sanırım gerçekçi olarak Yazıtipini tekrar tekrar yaratmayacağınızdan başka büyük bir fark yok. Varun'un statik bir yazı tipi kullanma fikri de aynı şeyi yapacaktır.
Kevin Coppock

1
Örnek kodunuzun son satırı setLayoutFont (tf, tv1, tv2, tv3, tv4, tv5) olmalıdır; setTypeface (tf, tv1, tv2, tv3, tv4, tv5) yerine?
Kyle Clegg

1
Bunu yapmamalısın ? recycleTypedArray values
CorayThan

1
Gradle kullanıyorsanız, özel ad alanı şu şekilde olmalıdırxmlns:custom="http://schemas.android.com/apk/res-auto"
Jabari

93

Bunu XML yoluyla yapmanın oldukça kolay bir yolu var. TextView'ı genişleten kendi widget'ınızı oluşturmanız yeterlidir.

İlk olarak, res / values ​​/ attrs.xml'de aşağıdaki içeriğe sahip bir dosya oluşturun:

<resources>
    <declare-styleable name="TypefacedTextView">
        <attr name="typeface" format="string" />
    </declare-styleable>
</resources>

Bundan sonra, özel widget'ınızı oluşturun:

package your.package.widget;

public class TypefacedTextView extends TextView {

    public TypefacedTextView(Context context, AttributeSet attrs) {
        super(context, attrs);

        //Typeface.createFromAsset doesn't work in the layout editor. Skipping...
        if (isInEditMode()) {
            return;
        }

        TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.TypefacedTextView);
        String fontName = styledAttrs.getString(R.styleable.TypefacedTextView_typeface);
        styledAttrs.recycle();

        if (fontName != null) {
            Typeface typeface = Typeface.createFromAsset(context.getAssets(), fontName);
            setTypeface(typeface);
        }
    }

}

Gördüğünüz gibi, yukarıdaki kod varlıklar / klasörün içindeki bir yazı tipini okuyacaktır. Bu örnek için, varlıklar klasöründe "custom.ttf" adlı bir dosya olduğunu varsayıyorum. Sonunda, XML'lerde widget'ı kullanın:

<your.package.widget.TypefacedTextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:your_namespace="http://schemas.android.com/apk/res/your.package"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Custom fonts in XML are easy"
    android:textColor="#FFF"
    android:textSize="14dip"
    your_namespace:typeface="custom.ttf" />

Not: Özel yazı tipinizi Eclipse'in düzen düzenleyicisinde göremezsiniz. Bu yüzden isInEditMode()çeki koydum . Ancak uygulamanızı çalıştırırsanız, özel yazı tipi bir cazibe gibi çalışacaktır.

Umarım yardımcı olur!


Bunu denemedim, ancak TextViewsınıfı genişleterek özel bir denetim oluşturdum ; içine yerleştirin ve typefacenormalde yaptığımız gibi düzende özel kontrolü kullandık ve benim için çalıştı ... Yine de basitti, yukarıdakiler ...
Mahendra Liya

1
Söylediğini tam olarak yaptım. Tek fark, bu bileşeni yeniden kullanılabilir hale getirmiş olmam, çünkü soru bunun XML yoluyla nasıl yapılacağını soruyor. Bunu XML yoluyla yapmanın gerçekten bir yolu var ve bunu yapmanın yolu bu :)
leocadiotine

Entegre edilmesi çok kolay kod. Benim için çalışıyor. Teşekkürler.
Durai

1
Bu, kabul edilen cevap olmalıdır. Güzel yazılmış. Teşekkürler!
Reaz Murshed

1
Müthiş, @DominikSuszczewicz! Cevabı güncelleyebilmem için lütfen kodu paylaşır mısınız?
leokadiotin

15

Roboto yazı tipine sahip TextView örneği:

attr.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

<declare-styleable name="RobotoTextView">
    <attr name="typeface"/>
</declare-styleable>

<attr name="typeface" format="enum">
    <enum name="roboto_thin" value="0"/>
    <enum name="roboto_thin_italic" value="1"/>
    <enum name="roboto_light" value="2"/>
    <enum name="roboto_light_italic" value="3"/>
    <enum name="roboto_regular" value="4"/>
    <enum name="roboto_italic" value="5"/>
    <enum name="roboto_medium" value="6"/>
    <enum name="roboto_medium_italic" value="7"/>
    <enum name="roboto_bold" value="8"/>
    <enum name="roboto_bold_italic" value="9"/>
    <enum name="roboto_black" value="10"/>
    <enum name="roboto_black_italic" value="11"/>
    <enum name="roboto_condensed" value="12"/>
    <enum name="roboto_condensed_italic" value="13"/>
    <enum name="roboto_condensed_bold" value="14"/>
    <enum name="roboto_condensed_bold_italic" value="15"/>
</attr>

</resources>

RobotoTextView.java:

public class RobotoTextView extends TextView {

/*
 * Permissible values ​​for the "typeface" attribute.
 */
private final static int ROBOTO_THIN = 0;
private final static int ROBOTO_THIN_ITALIC = 1;
private final static int ROBOTO_LIGHT = 2;
private final static int ROBOTO_LIGHT_ITALIC = 3;
private final static int ROBOTO_REGULAR = 4;
private final static int ROBOTO_ITALIC = 5;
private final static int ROBOTO_MEDIUM = 6;
private final static int ROBOTO_MEDIUM_ITALIC = 7;
private final static int ROBOTO_BOLD = 8;
private final static int ROBOTO_BOLD_ITALIC = 9;
private final static int ROBOTO_BLACK = 10;
private final static int ROBOTO_BLACK_ITALIC = 11;
private final static int ROBOTO_CONDENSED = 12;
private final static int ROBOTO_CONDENSED_ITALIC = 13;
private final static int ROBOTO_CONDENSED_BOLD = 14;
private final static int ROBOTO_CONDENSED_BOLD_ITALIC = 15;
/**
 * List of created typefaces for later reused.
 */
private final static SparseArray<Typeface> mTypefaces = new SparseArray<Typeface>(16);

/**
 * Simple constructor to use when creating a view from code.
 *
 * @param context The Context the view is running in, through which it can
 *                access the current theme, resources, etc.
 */
public RobotoTextView(Context context) {
    super(context);
}

/**
 * Constructor that is called when inflating a view from XML. This is called
 * when a view is being constructed from an XML file, supplying attributes
 * that were specified in the XML file. This version uses a default style of
 * 0, so the only attribute values applied are those in the Context's Theme
 * and the given AttributeSet.
 * <p/>
 * <p/>
 * The method onFinishInflate() will be called after all children have been
 * added.
 *
 * @param context The Context the view is running in, through which it can
 *                access the current theme, resources, etc.
 * @param attrs   The attributes of the XML tag that is inflating the view.
 * @see #RobotoTextView(Context, AttributeSet, int)
 */
public RobotoTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    parseAttributes(context, attrs);
}

/**
 * Perform inflation from XML and apply a class-specific base style. This
 * constructor of View allows subclasses to use their own base style when
 * they are inflating.
 *
 * @param context  The Context the view is running in, through which it can
 *                 access the current theme, resources, etc.
 * @param attrs    The attributes of the XML tag that is inflating the view.
 * @param defStyle The default style to apply to this view. If 0, no style
 *                 will be applied (beyond what is included in the theme). This may
 *                 either be an attribute resource, whose value will be retrieved
 *                 from the current theme, or an explicit style resource.
 * @see #RobotoTextView(Context, AttributeSet)
 */
public RobotoTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    parseAttributes(context, attrs);
}

/**
 * Parse the attributes.
 *
 * @param context The Context the view is running in, through which it can access the current theme, resources, etc.
 * @param attrs   The attributes of the XML tag that is inflating the view.
 */
private void parseAttributes(Context context, AttributeSet attrs) {
    TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.RobotoTextView);

    int typefaceValue = values.getInt(R.styleable.RobotoTextView_typeface, 0);
    values.recycle();

    setTypeface(obtaintTypeface(context, typefaceValue));
}

/**
 * Obtain typeface.
 *
 * @param context       The Context the view is running in, through which it can
 *                      access the current theme, resources, etc.
 * @param typefaceValue values ​​for the "typeface" attribute
 * @return Roboto {@link Typeface}
 * @throws IllegalArgumentException if unknown `typeface` attribute value.
 */
private Typeface obtaintTypeface(Context context, int typefaceValue) throws IllegalArgumentException {
    Typeface typeface = mTypefaces.get(typefaceValue);
    if (typeface == null) {
        typeface = createTypeface(context, typefaceValue);
        mTypefaces.put(typefaceValue, typeface);
    }
    return typeface;
}

/**
 * Create typeface from assets.
 *
 * @param context       The Context the view is running in, through which it can
 *                      access the current theme, resources, etc.
 * @param typefaceValue values ​​for the "typeface" attribute
 * @return Roboto {@link Typeface}
 * @throws IllegalArgumentException if unknown `typeface` attribute value.
 */
private Typeface createTypeface(Context context, int typefaceValue) throws IllegalArgumentException {
    Typeface typeface;
    switch (typefaceValue) {
        case ROBOTO_THIN:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Thin.ttf");
            break;
        case ROBOTO_THIN_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-ThinItalic.ttf");
            break;
        case ROBOTO_LIGHT:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Light.ttf");
            break;
        case ROBOTO_LIGHT_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-LightItalic.ttf");
            break;
        case ROBOTO_REGULAR:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Regular.ttf");
            break;
        case ROBOTO_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Italic.ttf");
            break;
        case ROBOTO_MEDIUM:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Medium.ttf");
            break;
        case ROBOTO_MEDIUM_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-MediumItalic.ttf");
            break;
        case ROBOTO_BOLD:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Bold.ttf");
            break;
        case ROBOTO_BOLD_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldItalic.ttf");
            break;
        case ROBOTO_BLACK:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Black.ttf");
            break;
        case ROBOTO_BLACK_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BlackItalic.ttf");
            break;
        case ROBOTO_CONDENSED:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Condensed.ttf");
            break;
        case ROBOTO_CONDENSED_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-CondensedItalic.ttf");
            break;
        case ROBOTO_CONDENSED_BOLD:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldCondensed.ttf");
            break;
        case ROBOTO_CONDENSED_BOLD_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldCondensedItalic.ttf");
            break;
        default:
            throw new IllegalArgumentException("Unknown `typeface` attribute value " + typefaceValue);
    }
    return typeface;
}

}

Kullanım örneği:

<your.package.widget.RobotoTextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:typeface="roboto_thin"
                android:textSize="22sp"
                android:text="Roboto Thin"/>

Kaynaklar: Roboto ve Noto yazı tipleri


java sınıfındaki fontların kimliklerini düzeltmeden bu çözümü kullanmanın bir yolu var mı? belki bu son alanları enum attrs'den okuyabilirsiniz .. private final static int ROBOTO_THIN = 0; özel nihai statik int ROBOTO_THIN_ITALIC = 1; özel nihai statik int ROBOTO_LIGHT = 2; ...
Arthur Melo

3

Çok geç, ancak benim diğerine yardımcı oluyor,
TypeFace adlı bir özniteliğe sahip olan ve önbelleğe almadan yazı tipi yüklemesiyle bellek sızıntısı sorunu olan CustomTextView'ı oluşturdum.

Öncelikle Fontsbir kez varlıklarından fontları yüklemek sınıf yalnızca

 import android.content.Context;
import android.graphics.Typeface;

import java.util.Hashtable;

/**
 * Created by tonyhaddad on 7/19/15.
 */
public class Fonts {
    private Context context;

    public Fonts(Context context) {
        this.context = context;
    }
    private static Hashtable<String, Typeface> sTypeFaces = new Hashtable<String, Typeface>(
            4);
    public static Typeface getTypeFace(Context context, String fileName) {
        Typeface tempTypeface = sTypeFaces.get(fileName);

        if (tempTypeface == null) {
            String fontPath=null;
            if(fileName=="metabold")
                fontPath ="fonts/Meta-Bold.ttf";

            else if(fileName=="metanormal")
                fontPath="fonts/Meta-Normal.ttf";
            else if(fileName=="gsligh")
                fontPath="fonts/gesslight.ttf";
            else if(fileName=="bold")
                fontPath="fonts/Lato-Bold.ttf";
            else if(fileName=="rcr")
                fontPath="fonts/RobotoCondensed-Regular.ttf";

            else if(fileName=="mpr")
                fontPath="fonts/MyriadPro-Regular.otf";
            else if(fileName=="rr")
                fontPath="fonts/Roboto-Regular.ttf";

            tempTypeface = Typeface.createFromAsset(context.getAssets(), fontPath);
            sTypeFaces.put(fileName, tempTypeface);
        }

        return tempTypeface;
    }
}

attrs.xml dosyasına özel bir öznitelik eklemeniz gerekir, bunu ekleyin

<declare-styleable name="CustomFontTextView">
        <attr name="typeFace" format="string" />

    </declare-styleable>

sonra özel sınıf

 package package_name;

/**
 * Created by tonyhaddad on 8/26/15.
 */

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;

import package_name.R;

public class CustomFontTextView extends TextView {

    String typeFace;


    public CustomFontTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if (isInEditMode()) {
            return;
        }
        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.CustomFontTextView,
                0, 0);
        try {
            typeFace = a.getString(0);
        } finally {
            a.recycle();
        }

        if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
        {
            Typeface tf = Fonts.getTypeFace(context, typeFace);
            setTypeface(tf);
        }
        init();
    }

    public CustomFontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (isInEditMode()) {
            return;
        }
        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.CustomFontTextView,
                0, 0);
        try {
            typeFace = a.getString(0);
        } finally {
            a.recycle();
        }

        if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
        {
            Typeface tf = Fonts.getTypeFace(context, typeFace);
            setTypeface(tf);
        }

        init();
    }

    public CustomFontTextView(Context context) {
        super(context);



        if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
        {
            Typeface tf = Fonts.getTypeFace(context, typeFace);
            setTypeface(tf);
        }
        init();
    }


    private void init() {

    }

    public String getTypeFace() {
        return typeFace;
    }

    public void setTypeFace(String typeFace) {
        this.typeFace = typeFace;
        invalidate();
        requestLayout();
    }
}

ve son olarak metin görünümünü ekleyin

  <package_name.CustomFontTextView
            xmlns:custom="http://schemas.android.com/apk/res-auto/package_name"
            android:id="@+id/txt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="41dp"
            android:gravity="center_vertical"
            android:text="text"
            android:textColor="#000"
            android:textSize="23sp"
            custom:typeFace="metanormal"/>

ve setTypeFace yöntemi ile yazı tipini progrmatik olarak değiştirebilir,
ayrıca bu görünümden birden fazlasını kullanmak istiyorsanız özel ad alanını ana mizanpajınıza taşıyabilirsiniz.

Mutlu Kodlama :)


basit stratight cevap.
eyadMhanna

2

OnCreate () 'de çağrılan ve en dıştaki ViewGroup'unuzdan geçen aşağıdaki yöntem, dinamik olarak oluşturulan metin (yani dinamik listeler, uyarılar vb.) Dışındaki her şey için çalışacaktır. En dıştaki ViewGroup'u elde etmenin kolay bir yolu, görünümlerinizden herhangi birinde getRootView kullanmaktır.

public void onCreate(Bundle savedInstanceState){
    //onCreate code...
    EditText text = (EditText) findViewById(R.id.editText1);
    setTypeFaceForViewGroup((ViewGroup) text.getRootView());
}

private void setTypeFaceForViewGroup(ViewGroup vg){

    for (int i = 0; i < vg.getChildCount(); i++) {

            if (vg.getChildAt(i) instanceof ViewGroup)
                setTypeFaceForViewGroup((ViewGroup) vg.getChildAt(i));

            else if (vg.getChildAt(i) instanceof TextView)
                ((TextView) vg.getChildAt(i)).setTypeface(Typeface.createFromAsset(getAssets(), "fonts/Your_Font.ttf"));

    }

}

Bu dinamik içerik için de işe yaramalı, onu çağırmanız, yarattığınız her şeyi, yarattıktan hemen sonra iletmeniz gerekir (yine de bunu test etmedim).

Hafızadan tasarruf etmek için, döngü her çalıştırdığımda yeni bir tane oluşturmak yerine muhtemelen yazı tipini statik bir değişken yapmak isteyeceksiniz.


Bu çözümü önermiyorum, çünkü uygulamak istediğiniz her öğe için aynı fontun yeni bir örneğini oluşturuyorsunuz. Bu, bellek sorunlarına neden olabilir.
flawyte

Sonunda notumda yer alıyor.
Chris

2

Daha genel bir programatik çözüm arıyorsanız, tüm görünümün Yazı Tipini (Etkinlik Kullanıcı Arabirimi) ayarlamak için kullanılabilecek statik bir sınıf oluşturdum. Mono (C #) ile çalıştığımı ancak Java kullanarak kolayca uygulayabileceğinizi unutmayın.

Bu sınıfa, özelleştirmek istediğiniz bir düzen veya belirli bir görünüm iletebilirsiniz. Süper verimli olmak istiyorsanız, bunu Singleton modelini kullanarak uygulayabilirsiniz.

public static class AndroidTypefaceUtility 
{
    static AndroidTypefaceUtility()
    {
    }
    //Refer to the code block beneath this one, to see how to create a typeface.
    public static void SetTypefaceOfView(View view, Typeface customTypeface)
    {
    if (customTypeface != null && view != null)
    {
            try
            {
                if (view is TextView)
                    (view as TextView).Typeface = customTypeface;
                else if (view is Button)
                    (view as Button).Typeface = customTypeface;
                else if (view is EditText)
                    (view as EditText).Typeface = customTypeface;
                else if (view is ViewGroup)
                    SetTypefaceOfViewGroup((view as ViewGroup), customTypeface);
                else
                    Console.Error.WriteLine("AndroidTypefaceUtility: {0} is type of {1} and does not have a typeface property", view.Id, typeof(View));
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine("AndroidTypefaceUtility threw:\n{0}\n{1}", ex.GetType(), ex.StackTrace);
                    throw ex;
                }
            }
            else
            {
                Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / view parameter should not be null");
            }
        }

        public static void SetTypefaceOfViewGroup(ViewGroup layout, Typeface customTypeface)
        {
            if (customTypeface != null && layout != null)
            {
                for (int i = 0; i < layout.ChildCount; i++)
                {
                    SetTypefaceOfView(layout.GetChildAt(i), customTypeface);
                }
            }
            else
            {
                Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / layout parameter should not be null");
            }
        }

    }

Aktivitenizde bir Typeface nesnesi oluşturmanız gerekecektir. Kaynaklar / Varlıklar / dizinime yerleştirilmiş bir .ttf dosyası kullanarak OnCreate () 'de benimkini oluşturuyorum. Dosyanın, özelliklerinde Android Varlığı olarak işaretlendiğinden emin olun.

protected override void OnCreate(Bundle bundle)
{               
    ...
    LinearLayout rootLayout = (LinearLayout)FindViewById<LinearLayout>(Resource.Id.signInView_LinearLayout);
    Typeface allerTypeface = Typeface.CreateFromAsset(base.Assets,"Aller_Rg.ttf");
    AndroidTypefaceUtility.SetTypefaceOfViewGroup(rootLayout, allerTypeface);
}

2

Maalesef Android, tüm uygulamanız için yazı tipini değiştirmek için aradığınız hızlı, kolay ve net yolu sağlamaz. Ancak son zamanlarda bu konuyu inceledim ve yazı tipini herhangi bir kodlama olmadan değiştirmenize izin veren bazı araçlar yarattım (hepsini xml, stiller ve hatta metin görünümleri aracılığıyla yapabilirsiniz). Buradaki diğer cevaplarda gördüğünüz gibi benzer çözümlere dayanıyorlar, ancak çok daha fazla esneklik sağlıyorlar. Bununla ilgili her şeyi bu blogda okuyabilir ve github projesini buradan görebilirsiniz .

İşte bu araçların nasıl uygulanacağına dair bir örnek. Tüm yazı tipi dosyalarınızı koyun assets/fonts/. Ardından, bu yazı tiplerini bir xml dosyasında (örn. res/xml/fonts.xml) Bildirin ve bu dosyayı uygulamanızın başlarında TypefaceManager.initialize(this, R.xml.fonts);(örn. OnCreate of your Application sınıfında) yükleyin. Xml dosyası şuna benzer:

<?xml version="1.0" encoding="utf-8"?>
<familyset>

    <!-- Some Font. Can be referenced with 'someFont' or 'aspergit' -->
    <family>
        <nameset>
            <name>aspergit</name>
            <name>someFont</name>
        </nameset>
        <fileset>
            <file>Aspergit.ttf</file>
            <file>Aspergit Bold.ttf</file>
            <file>Aspergit Italic.ttf</file>
            <file>Aspergit Bold Italic.ttf</file>
        </fileset>
    </family>

    <!-- Another Font. Can be referenced with 'anotherFont' or 'bodoni' -->
    <family>
        <nameset>
            <name>bodoni</name>
            <name>anotherFont</name>
        </nameset>
        <fileset>
            <file>BodoniFLF-Roman.ttf</file>
            <file>BodoniFLF-Bold.ttf</file>
        </fileset>
    </family>

</familyset>

Artık bu yazı tiplerini kendi stilinizde veya xml'de (yukarıda bahsettiğim araçları kullanmanız koşuluyla), com.innovattic.font.FontTextViewxml düzeninizdeki özel UI öğesini kullanarak kullanabilirsiniz . Aşağıda, yalnızca düzenleyerek tüm uygulamanızdaki tüm metinlere bir yazı tipini nasıl uygulayabileceğinizi görebilirsiniz res/values/styles.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">

    <!-- Application theme -->
    <!-- Use a different parent if you don't want Holo Light -->
    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
        <item name="android:textViewStyle">@style/MyTextViewStyle</item>
    </style>

    <!-- Style to use for ALL text views (including FontTextView) -->
    <!-- Use a different parent if you don't want Holo Light -->
    <style name="MyTextViewStyle" parent="@android:style/Widget.Holo.Light.TextView">
        <item name="android:textAppearance">@style/MyTextAppearance</item>
    </style>

    <!-- Text appearance to use for ALL text views (including FontTextView) -->
    <!-- Use a different parent if you don't want Holo Light -->
    <style name="MyTextAppearance" parent="@android:style/TextAppearance.Holo">
        <!-- Alternatively, reference this font with the name "aspergit" -->
        <!-- Note that only our own TextView's will use the font attribute -->
        <item name="flFont">someFont</item>
        <item name="android:textStyle">bold|italic</item>
    </style>

    <!-- Alternative style, maybe for some other widget -->
    <style name="StylishFont">
        <item name="flFont">anotherFont</item>
        <item name="android:textStyle">normal</item>
    </style>

</resources>

Eşlik eden res/layout/layout.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <!-- This text view is styled with the app theme -->
    <com.innovattic.font.FontTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This uses my font in bold italic style" />

    <!-- This text view is styled here and overrides the app theme -->
    <com.innovattic.font.FontTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:flFont="anotherFont"
        android:textStyle="normal"
        android:text="This uses another font in normal style" />

    <!-- This text view is styled with a style and overrides the app theme -->
    <com.innovattic.font.FontTextView
        style="@style/StylishFont"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This also uses another font in normal style" />

</LinearLayout>

Temayı Android bildiriminize uygulamayı unutmayın.


2

'Nin harika çözümüne bir not eklemek istiyorum leocadiotine. Mükemmeldir, ancak bu Özel Metin Görünümü kullanıldığında, her metin görünümü oluşturulduğunda varlıklara erişmesi gerektiğinden, çoğu zaman uygulamayı yavaşlatır. Ben böyle bir şey kullanmak önermek View Holder patternde Adapters, ben bir örnek yazdı:

public class Fonts {

    private static final Map<String, Typeface> typefaces = new HashMap<String, Typeface>();

    public static Typeface getTypeface(Context ctx, String fontName) {
        Typeface typeface = typefaces.get(fontName);
        if (typeface == null) {
            typeface = Typeface.createFromAsset(ctx.getAssets(), fontName);
            typefaces.put(fontName, typeface);
        }
        return typeface;
    } 
}

Bu şekilde, uygulama varlıklara varlık başına yalnızca bir kez erişir ve bunları daha fazla ihtiyaç için bellekte tutar.


0

Tüm uygulamayı değiştirip değiştirmediğini bilmiyorum, ancak bunu yaparak başka türlü değiştirilemeyen bazı bileşenleri değiştirmeyi başardım:

Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/Lucida Sans Unicode.ttf");
Typeface.class.getField("DEFAULT").setAccessible(true);
Typeface.class.getField("DEFAULT_BOLD").setAccessible(true);
Typeface.class.getField("DEFAULT").set(null, tf);
Typeface.class.getField("DEFAULT_BOLD").set(null, tf);

@richard, yerel ayara göre özel yazı tipini ayarlamak istiyorum.Örneğin, İngilizce yerel ayarını kullandığımızda Arial TTF'yi ayarlamak ve Kore loacale
Ji'yi

0

Bu bağlantıda adım adım bilgi buldum, bağlantı: https://github.com/jaydipumaretiya/CustomTypeface/

Android'de yazı tipini doğru kullanmanın birçok yolu vardır, yazı tipi dosyanızı doğrudan ana klasörünüzün altındaki varlıklar klasörüne koymanız gerekir ve çalışma zamanını kullanabilirsiniz.

Diğer en basit yol, xml dosyanızda yazı tipi ayarlamak için varsayılan kitaplığı kullanmaktır. Bu özel yazı tipi kitaplığını, yazı tipini TextView, EditText, Button, CheckBox, RadioButton ve AutoCompleteTextView ve android'deki diğer wedget olarak ayarlamak için tercih ediyorum.


0

Android 8.0 (API seviyesi 26), XML'de Yazı Tipleri adlı yeni bir özellik sunar. Bir fontfamily dosyası oluşturabilir ve bunu styles.xml'de ayarlayabilirsiniz.

Yazı tiplerini kaynak olarak eklemek için Android Studio'da aşağıdaki adımları uygulayın:

1. res klasörüne sağ tıklayın ve Yeni> Android kaynak dizinine gidin. Yeni Kaynak Dizini penceresi açılır.

2. Kaynak türü listesinde yazı tipini seçin ve ardından Tamam'a tıklayın. Not: Kaynak dizinin adı yazı tipi olmalıdır.

3. Yazı tipi dosyalarınızı yazı tipi klasörüne ekleyin.

Bir yazı tipi ailesi oluşturmak için aşağıdaki adımları uygulayın:

1. Yazı tipi klasörüne sağ tıklayın ve Yeni> Yazı tipi kaynak dosyasına gidin. Yeni Kaynak Dosyası penceresi açılır.

2. Dosya adını girin ve ardından Tamam'a tıklayın. Yeni yazı tipi kaynağı XML'si düzenleyicide açılır.

3. Öğedeki her bir yazı tipi dosyasını, stili ve ağırlık özniteliğini kesin. Aşağıdaki XML, yazı tipi kaynağı XML'ine yazı tipiyle ilgili özniteliklerin eklenmesini gösterir:

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
    <font
        android:fontStyle="normal"
        android:fontWeight="400"
        android:font="@font/lobster_regular" />
    <font
        android:fontStyle="italic"
        android:fontWeight="400"
        android:font="@font/lobster_italic" />
</font-family>

Stile yazı tipi ekleme

Styles.xml dosyasını açın ve fontFamily özniteliğini erişmek istediğiniz yazı tipi dosyasına ayarlayın.

 <style name="customfontstyle" parent="@android:style/TextAppearance.Small">
    <item name="android:fontFamily">@font/lobster</item>
</style>

Kaynak: XML'deki Yazı Tipleri

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.