wake-up-neo.com

Android: Sie möchten benutzerdefinierte Schriftarten für die gesamte Anwendung und nicht für die Laufzeit festlegen

Ist es möglich, in jedem Steuerelement der Anwendung eine benutzerdefinierte Schriftart festzulegen? Und nicht unbedingt Laufzeit? (d. h. aus xml oder nur einmal für die gesamte Anwendung in der Java-Datei)

Ich kann die Schriftart für ein Steuerelement aus diesem Code festlegen.

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

    textView.setTypeface(tf);

}

Das Problem bei diesem Code ist, dass er für jede Kontrolle aufgerufen werden muss. Und ich möchte diese oder eine ähnliche Methode einmal aufrufen oder wenn möglich die Eigenschaft in xml setzen. Ist es möglich?

95
Prasham

EDIT: Es ist also eine Weile her, und ich möchte hinzufügen, was ich denke, ist der beste Weg, dies zu tun, und durch XML nicht weniger!

Zuerst möchten Sie also eine neue Klasse erstellen, die die Ansicht überschreibt, die Sie anpassen möchten. (möchten Sie beispielsweise eine Schaltfläche mit einer benutzerdefinierten Schriftart? Erweitern Sie Button). Lassen Sie uns ein Beispiel machen:

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

Wenn Sie noch keines haben, fügen Sie ein XML-Dokument unter res/values/attrs.xml hinzu und fügen Sie Folgendes hinzu:

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

Okay, wenn wir aus dem Weg sind, kommen wir zurück zur parseAttributes()-Methode von früher:

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();
}

Jetzt bist du fertig. Sie können weitere Attribute für alles hinzufügen (Sie können für TypefaceStyle weitere Attribute hinzufügen - fett, kursiv usw.), aber nun sehen wir uns an, wie man es benutzt:

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

Die xmlns:custom-Zeile kann wirklich alles sein, aber die Konvention ist das, was oben gezeigt wird. Was zählt ist, dass es einzigartig ist, und deshalb wird der Paketname verwendet. Jetzt verwenden Sie einfach das custom:-Präfix für Ihre Attribute und das Android:-Präfix für Android-Attribute.

Eine letzte Sache: Wenn Sie dies in einem Stil (res/values/styles.xml) verwenden möchten, sollten Sie nicht die xmlns:custom-Zeile hinzufügen. Verweisen Sie einfach den Namen des Attributs ohne Präfix:

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

                               (PREVIOUS ANSWER)

Verwenden einer benutzerdefinierten Schrift in Android

Das sollte helfen. Grundsätzlich gibt es keine Möglichkeit, dies in XML zu tun, und soweit ich das beurteilen kann, gibt es keine einfachere Möglichkeit, dies im Code zu tun. Sie können immer eine setLayoutFont () -Methode haben, die die Schriftart einmal erstellt und dann setTypeface () für jede ausführt. Sie müssen es nur jedes Mal aktualisieren, wenn Sie ein neues Element zu einem Layout hinzufügen. Etwas wie unten:

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

EDIT: Also bin ich gerade dazu gekommen, so etwas selbst zu implementieren, und wie ich es am Ende getan habe, war eine Funktion wie die folgende:

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

Dann verwenden Sie einfach diese Methode von onCreate () und übergeben alle TextViews, die Sie aktualisieren möchten:

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

EDIT 05.09.12:

Da dies immer noch Meinungen und Stimmen enthält, möchte ich eine viel bessere und vollständigere Methode hinzufügen:

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

Wenn Sie den Stamm Ihres Layouts übergeben, wird rekursiv nach TextView- oder Button-Ansichten (oder anderen, die Sie diese if-Anweisung hinzufügen) in diesem Layout gesucht und die Schriftart festgelegt, ohne dass Sie sie nach ID angeben müssen. Dies setzt natürlich voraus, dass Sie die Schriftart auf every view setzen möchten.

122
kcoppock

Es gibt einen recht einfachen Weg, dies über XML zu tun. Sie müssen lediglich ein eigenes Widget erstellen, das TextView erweitert.

Erstellen Sie zunächst eine Datei in res/values ​​/ attrs.xml mit folgendem Inhalt:

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

Danach erstellen Sie Ihr benutzerdefiniertes Widget:

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

}

Wie Sie sehen, liest der obige Code eine Schrift innerhalb des Assets/Ordners. In diesem Beispiel gehe ich davon aus, dass sich im Assets-Ordner eine Datei mit dem Namen "custom.ttf" befindet. Verwenden Sie schließlich das Widget in den XMLs:

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

Hinweis: Sie können Ihre benutzerdefinierte Schriftart nicht im Layout-Editor von Eclipse anzeigen. Deshalb stelle ich den isInEditMode()-Check. Wenn Sie Ihre App ausführen, funktioniert die benutzerdefinierte Schriftart jedoch wie ein Zauber.

Ich hoffe es hilft!

90
leocadiotine

Beispiel für TextView mit Roboto-Schrift:

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

}

Anwendungsbeispiel:

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

Ressourcen: Roboto & Noto-Schriftarten

15
e.shishkin

Es ist zu spät, aber es hilft dem anderen
Ich habe CustomTextView erstellt, das ein Attribut namens typeFace hat und sich um Speicherleckprobleme mit dem Laden von Schriftarten ohne Zwischenspeicherung kümmert

Erstens Fonts-Klasse, die die Zeichensätze nur einmal aus Assets lädt 

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

dann müssen Sie ein benutzerdefiniertes Attribut in der Datei attrs.xml hinzufügen, fügen Sie dieses hinzu 

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

    </declare-styleable>

dann benutzerdefinierte Klasse 

 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();
    }
}

und fügen Sie schließlich die Textansicht hinzu 

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

und Sie können die Schrift mit der setTypeFace-Methode fortlaufend ändern
Sie können auch den benutzerdefinierten Namespace in Ihr übergeordnetes Layout verschieben, wenn Sie mehr als einen aus dieser Ansicht verwenden möchten 

Glückliche Kodierung :)

3
Antwan

Wenn Sie nach einer allgemeineren programmatischen Lösung suchen, habe ich eine statische Klasse erstellt, mit der die Schriftart einer gesamten Ansicht (Aktivitätsbenutzeroberfläche) festgelegt werden kann. Beachten Sie, dass ich mit Mono (C #) arbeite. Sie können es jedoch leicht mit Java implementieren.

Sie können dieser Klasse ein Layout oder eine bestimmte Ansicht übergeben, die Sie anpassen möchten. Wenn Sie sehr effizient sein möchten, können Sie es mithilfe des Singleton-Musters implementieren.

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");
            }
        }

    }

In Ihrer Aktivität müssen Sie ein Typeface-Objekt erstellen. Ich erstelle meine in OnCreate () mit einer .ttf-Datei, die sich in meinem Resources/Assets/-Verzeichnis befindet. Stellen Sie sicher, dass die Datei in ihren Eigenschaften als Android-Asset markiert ist.

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
JCKortlang

Die folgende Methode, die in onCreate () aufgerufen wird und Ihre äußerste ViewGroup übergeben hat, funktioniert für alles außer Text, der dynamisch erstellt wird (z. B. dynamische Listen, Alarme usw.). Die einfachste Möglichkeit, die äußerste ViewGroup abzurufen, besteht in der Verwendung von getRootView in einer beliebigen Ihrer Ansichten.

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"));

    }

}

Dies sollte auch für dynamische Inhalte funktionieren. Sie müssten es einfach anrufen und alles, was Sie erstellt haben, direkt nach der Erstellung übergeben (ich habe es jedoch nicht getestet).

Um Speicherplatz zu sparen, sollten Sie die Schrift wahrscheinlich zu einer statischen Variablen machen, anstatt jedes Mal eine neue zu erstellen, wenn die Schleife wie hier ausgeführt wird.

2
Chris

Ich möchte der großartigen Lösung von leocadiotine eine Anmerkung hinzufügen. Es ist perfekt, aber bei Verwendung dieser benutzerdefinierten Textansicht verlangsamt sich die Anwendung viel Zeit, da sie bei jeder Erstellung einer Textansicht auf die Elemente zugreifen muss. Ich schlage vor, etwas wie den View Holder pattern in der Adapters zu verwenden, ich schrieb ein Beispiel:

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

Auf diese Weise greift die Anwendung nur einmal pro Asset auf die Assets zu und speichert sie für weitere Anforderungen.

2
Emaborsa

Leider bietet Android nicht die schnelle, einfache und saubere Möglichkeit, die Schriftart für Ihre gesamte App zu ändern. Aber in letzter Zeit habe ich mich mit dieser Angelegenheit befasst und einige Werkzeuge erstellt, mit denen Sie die Schriftart ohne Codierung ändern können (Sie können dies alles durch XML, Stile und sogar Textdarstellungen machen). Sie basieren auf ähnlichen Lösungen, wie Sie sie in den anderen Antworten sehen, erlauben aber weitaus mehr Flexibilität. Sie können alles darüber in diesem Blog lesen und das Github-Projekt hier sehen.

Hier ist ein Beispiel für die Anwendung dieser Tools. Legen Sie alle Ihre Schriftdateien in assets/fonts/ ab. Deklarieren Sie dann diese Schriftarten in einer XML-Datei (z. B. res/xml/fonts.xml) und laden Sie diese Datei früh in Ihrer App mit TypefaceManager.initialize(this, R.xml.fonts); (z. B. in onCreate Ihrer Application-Klasse). Die XML-Datei sieht folgendermaßen aus:

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

Jetzt können Sie diese Schriftarten in Ihrem Style oder XML verwenden (sofern Sie die oben genannten Tools verwenden), indem Sie das benutzerdefinierte Oberflächenelement com.innovattic.font.FontTextView in Ihrem XML-Layout verwenden. Nachfolgend können Sie sehen, wie Sie eine Schrift auf alle Texte in Ihrer gesamten App anwenden können, indem Sie einfach res/values/styles.xml bearbeiten:

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

Mit dem beiliegenden 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>

Vergessen Sie nicht, das Design in Ihrem Android-Manifest anzuwenden.

2
Jelle Fresen

Android 8.0 (API Level 26) führt eine neue Funktion ein, Fonts in XML. Sie können eine Fontfamily-Datei erstellen und in styles.xml festlegen.

Um Zeichensätze als Ressourcen hinzuzufügen, führen Sie die folgenden Schritte in Android aus Studio:

1.Klicken Sie mit der rechten Maustaste auf den Ordner res und wechseln Sie zu Neu> Android-Ressourcenverzeichnis. Das Fenster New Resource Directory wird angezeigt.

2. Wählen Sie in der Liste Ressourcentyp die Schriftart aus und klicken Sie auf OK. Hinweis: Der Name des Ressourcenverzeichnisses muss Schriftart sein.

3.Fügen Sie Ihre Schriftartendateien im Schriftartordner hinzu.

Um eine Schriftfamilie zu erstellen, führen Sie die folgenden Schritte aus:

1.Klicken Sie mit der rechten Maustaste auf den Schriftartordner und wählen Sie Neu> Schriftartressourcendatei. Das Fenster "Neue Ressourcendatei" wird angezeigt.

2.Geben Sie den Dateinamen ein und klicken Sie auf OK. Die neue XML-Schriftartressource wird im Editor geöffnet.

3.Schließen Sie alle Schriftdatei-, Stil- und Gewichtsattribute im Element ein. Die folgende XML veranschaulicht das Hinzufügen von Attributen in Bezug auf Schriftarten in der Fontressource XML:

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

Schriftarten zum Stil hinzufügen

Öffnen Sie die Datei styles.xml und setzen Sie das fontFamily-Attribut auf die Schriftartdatei Sie möchten zugreifen.

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

Quelle: Schriftarten in XML

0

Ich habe unter diesem Link Schritt für Schritt Informationen gefunden, Link: https://github.com/jaydipumaretiya/CustomTypeface/

Es gibt viele Möglichkeiten, die Schriftart in Android korrekt zu verwenden. Sie müssen die Schriftartdatei im -Ordner-Ordner direkt unter Ihrem Hauptordner ablegen und zur Laufzeit verwenden.

Eine andere einfache Möglichkeit besteht darin, die Standardbibliothek zu verwenden, um die Schriftart in Ihrer XML-Datei festzulegen. Ich habe diese benutzerdefinierte Schriftartbibliothek vorgezogen, um die Schriftart auf TextView, EditText, Button, CheckBox, .__ zu setzen. RadioButton und AutoCompleteTextView und andere Symbole in Android.

0
Mehul Rakholiya

Ich weiß nicht, ob sich dadurch die gesamte App ändert, aber es ist mir gelungen, einige Komponenten zu ändern, die sonst nicht geändert werden könnten:

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);
0
Richard