web-dev-qa-db-ger.com

Verwenden einer benutzerdefinierten Schrift in Android

Ich möchte eine benutzerdefinierte Schriftart für meine Android-Anwendung verwenden, die ich erstelle.
Ich kann die Schrift jedes Objekts individuell von Code aus ändern, aber ich habe Hunderte davon.

So,

  • Gibt es eine Möglichkeit, dies aus XML heraus zu tun? [Festlegen einer benutzerdefinierten Schriftart]
  • Gibt es eine Möglichkeit, den Code an einer Stelle auszuführen, um zu sagen, dass die gesamte Anwendung und alle Komponenten die benutzerdefinierte Schriftart anstelle der Standardschrift verwenden sollten?
110
Codevalley

Gibt es eine Möglichkeit, dies über die XML?

Nein Entschuldigung. Sie können die integrierten Schriftarten nur über XML angeben.

Gibt es eine Möglichkeit, dies aus dem Code in .__ zu tun. ein Ort, um zu sagen, dass das Ganze Anwendung und alle Komponenten Verwenden Sie stattdessen die benutzerdefinierte Schriftart der Standardeinstellung?

Nicht dass ich wüsste.

Heutzutage gibt es eine Vielzahl von Optionen:

  • Fontressourcen und Backports im Android SDK, wenn Sie appcompat verwenden

  • Bibliotheken von Drittanbietern für diejenigen, die nicht appcompat verwenden, obwohl nicht alle die Definition der Schriftart in Layoutressourcen unterstützen

82
CommonsWare

Ja, es ist möglich.

Sie müssen eine benutzerdefinierte Ansicht erstellen, die die Textansicht erweitert.

In attrs.xml im values Ordner:

<resources>
    <declare-styleable name="MyTextView">
        <attr name="first_name" format="string"/>
        <attr name="last_name" format="string"/>
        <attr name="ttf_name" format="string"/>
    </declare-styleable>
</resources>

In main.xml:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
     xmlns:lht="http://schemas.Android.com/apk/res/com.lht"
    Android:orientation="vertical"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    >
    <TextView  Android:layout_width="fill_parent" 
        Android:layout_height="wrap_content"
        Android:text="Hello"/>
    <com.lht.ui.MyTextView  
        Android:id="@+id/MyTextView"
        Android:layout_width="fill_parent" 
        Android:layout_height="wrap_content"
        Android:text="Hello friends"
        lht:ttf_name="ITCBLKAD.TTF"
        />   
</LinearLayout>

In MyTextView.Java:

package com.lht.ui;

import Android.content.Context;
import Android.graphics.Typeface;
import Android.util.AttributeSet;
import Android.util.Log;
import Android.widget.TextView;

public class MyTextView extends TextView {

    Context context;
    String ttfName;

    String TAG = getClass().getName();

    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;

        for (int i = 0; i < attrs.getAttributeCount(); i++) {
            Log.i(TAG, attrs.getAttributeName(i));
            /*
             * Read value of custom attributes
             */

            this.ttfName = attrs.getAttributeValue(
                    "http://schemas.Android.com/apk/res/com.lht", "ttf_name");
            Log.i(TAG, "firstText " + firstText);
            // Log.i(TAG, "lastText "+ lastText);

            init();
        }

    }

    private void init() {
        Typeface font = Typeface.createFromAsset(context.getAssets(), ttfName);
        setTypeface(font);
    }

    @Override
    public void setTypeface(Typeface tf) {

        // TODO Auto-generated method stub
        super.setTypeface(tf);
    }

}
109
Manish Singla

Ich habe dies auf eine "brachialere" Weise getan, die keine Änderungen an der Layout-XML oder den Aktivitäten erfordert. 

Getestet auf Android Version 2.1 bis 4.4. Führen Sie dies beim Start der App in Ihrer Application-Klasse aus: 

private void setDefaultFont() {

    try {
        final Typeface bold = Typeface.createFromAsset(getAssets(), DEFAULT_BOLD_FONT_FILENAME);
        final Typeface italic = Typeface.createFromAsset(getAssets(), DEFAULT_ITALIC_FONT_FILENAME);
        final Typeface boldItalic = Typeface.createFromAsset(getAssets(), DEFAULT_BOLD_ITALIC_FONT_FILENAME);
        final Typeface regular = Typeface.createFromAsset(getAssets(),DEFAULT_NORMAL_FONT_FILENAME);

        Field DEFAULT = Typeface.class.getDeclaredField("DEFAULT");
        DEFAULT.setAccessible(true);
        DEFAULT.set(null, regular);

        Field DEFAULT_BOLD = Typeface.class.getDeclaredField("DEFAULT_BOLD");
        DEFAULT_BOLD.setAccessible(true);
        DEFAULT_BOLD.set(null, bold);

        Field sDefaults = Typeface.class.getDeclaredField("sDefaults");
        sDefaults.setAccessible(true);
        sDefaults.set(null, new Typeface[]{
                regular, bold, italic, boldItalic
        });

    } catch (NoSuchFieldException e) {
        logFontError(e);
    } catch (IllegalAccessException e) {
        logFontError(e);
    } catch (Throwable e) {
        //cannot crash app if there is a failure with overriding the default font!
        logFontError(e);
    }
}

Ein vollständigeres Beispiel finden Sie unter http://github.com/perchrh/FontOverrideExample

49
P-chan

Obwohl ich die Antwort von Manish als die schnellste und zielgerichteteste Methode aufgreife, habe ich auch naive Lösungen gesehen, die einfach rekursiv durch eine Ansichtshierarchie laufen und die Schriften aller Elemente der Reihe nach aktualisieren. Etwas wie das:

public static void applyFonts(final View v, Typeface fontToSet)
{
    try {
        if (v instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) v;
            for (int i = 0; i < vg.getChildCount(); i++) {
                View child = vg.getChildAt(i);
                applyFonts(child, fontToSet);
            }
        } else if (v instanceof TextView) {
            ((TextView)v).setTypeface(fontToSet);
        }
    } catch (Exception e) {
        e.printStackTrace();
        // ignore
    }
}

Sie müssen diese Funktion in Ihren Ansichten sowohl nach dem Aufblasen des Layouts als auch in den onContentChanged()-Methoden Ihrer Aktivität aufrufen.

36
pospi

Ich konnte dies zentral erledigen, hier ist das Ergebnis:

enter image description here

Ich habe folgendes Activity und erweitere es, wenn ich benutzerdefinierte Schriftarten brauche:

import Android.app.Activity;
import Android.content.Context;
import Android.os.Bundle;
import Android.util.AttributeSet;
import Android.view.LayoutInflater.Factory;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.widget.TextView;

public class CustomFontActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    getLayoutInflater().setFactory(new Factory() {

        @Override
        public View onCreateView(String name, Context context,
                AttributeSet attrs) {
            View v = tryInflate(name, context, attrs);
            if (v instanceof TextView) {
                setTypeFace((TextView) v);
            }
            return v;
        }
    });
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

private View tryInflate(String name, Context context, AttributeSet attrs) {
    LayoutInflater li = LayoutInflater.from(context);
    View v = null;
    try {
        v = li.createView(name, null, attrs); 
    } catch (Exception e) {
        try {
            v = li.createView("Android.widget." + name, null, attrs);
        } catch (Exception e1) {
        }
    }
    return v;
}

private void setTypeFace(TextView tv) {
    tv.setTypeface(FontUtils.getFonts(this, "MTCORSVA.TTF"));
}
}

Wenn ich jedoch eine Aktivität aus dem Support-Paket verwende, z. FragmentActivity dann verwende ich diese Activity

import Android.annotation.TargetApi;
import Android.content.Context;
import Android.os.Build;
import Android.os.Bundle;
import Android.support.v4.app.FragmentActivity;
import Android.util.AttributeSet;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.widget.TextView;

public class CustomFontFragmentActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

// we can't setLayout Factory as its already set by FragmentActivity so we
// use this approach
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
    View v = super.onCreateView(name, context, attrs);
    if (v == null) {
        v = tryInflate(name, context, attrs);
        if (v instanceof TextView) {
            setTypeFace((TextView) v);
        }
    }
    return v;
}

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public View onCreateView(View parent, String name, Context context,
        AttributeSet attrs) {
    View v = super.onCreateView(parent, name, context, attrs);
    if (v == null) {
        v = tryInflate(name, context, attrs);
        if (v instanceof TextView) {
            setTypeFace((TextView) v);
        }
    }
    return v;
}

private View tryInflate(String name, Context context, AttributeSet attrs) {
    LayoutInflater li = LayoutInflater.from(context);
    View v = null;
    try {
        v = li.createView(name, null, attrs);
    } catch (Exception e) {
        try {
            v = li.createView("Android.widget." + name, null, attrs);
        } catch (Exception e1) {
        }
    }
    return v;
}

private void setTypeFace(TextView tv) {
    tv.setTypeface(FontUtils.getFonts(this, "MTCORSVA.TTF"));
}
}

Ich habe diesen Code noch nicht mit Fragments getestet, aber hoffentlich wird es funktionieren. 

Meine FontUtils ist einfach, wodurch auch das hier erwähnte Problem vor dem ICS gelöst wird https://code.google.com/p/Android/issues/detail?id=9904 :

import Java.util.HashMap;
import Java.util.Map;

import Android.content.Context;
import Android.graphics.Typeface;

public class FontUtils {

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

public static Typeface getFonts(Context context, String name) { 
    Typeface typeface = TYPEFACE.get(name);
    if (typeface == null) {
        typeface = Typeface.createFromAsset(context.getAssets(), "fonts/"
                + name);
        TYPEFACE.put(name, typeface);
    }
    return typeface;
}
}
23
M-WaJeEh

Hey, ich brauche auch 2 verschiedene Schriftarten in meiner App für verschiedene Widgets! Ich verwende diesen Weg:

In meiner Application-Klasse erstelle ich eine statische Methode:

public static Typeface getTypeface(Context context, String typeface) {
    if (mFont == null) {
        mFont = Typeface.createFromAsset(context.getAssets(), typeface);
    }
    return mFont;
}

Der String-Schrifttyp steht für die xyz.ttf im Asset-Ordner. (Ich habe eine Konstantenklasse erstellt) Jetzt können Sie diese in Ihrer App überall verwenden:

mTextView = (TextView) findViewById(R.id.text_view);
mTextView.setTypeface(MyApplication.getTypeface(this, Constants.TYPEFACE_XY));

Das einzige Problem ist, dass Sie dies für jedes Widget benötigen, bei dem Sie die Schrift verwenden möchten! Aber ich denke, das ist der beste Weg.

10
Informatic0re

Ich habe auf dem Blog von Lisa Wray eine nette Lösung gefunden. Mit der neuen Datenbindung ist es möglich, die Schriftart in Ihren XML-Dateien festzulegen.

@BindingAdapter({"bind:font"})
public static void setFont(TextView textView, String fontName){
    textView.setTypeface(Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + fontName));
}

In XML:

<TextView
app:font="@{`Source-Sans-Pro-Regular.ttf`}"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"/>
4
userM1433372

Mit pospi's Suggestion und dem Arbeiten mit der 'tag'-Eigenschaft wie Richard did habe ich eine benutzerdefinierte Klasse erstellt, die meine benutzerdefinierten Schriftarten lädt und sie entsprechend ihren Tags auf die Ansichten anwendet.

Anstatt also das TypeFace im Attribut Android: fontFamily festzulegen, verwenden Sie das Android: -Tag attritube und setzen es auf eines der definierten Enums.

public class Fonts {
    private AssetManager mngr;

    public Fonts(Context context) {
        mngr = context.getAssets();
    }
    private enum AssetTypefaces {
        RobotoLight,
        RobotoThin,
        RobotoCondensedBold,
        RobotoCondensedLight,
        RobotoCondensedRegular
    }

    private Typeface getTypeface(AssetTypefaces font) {
        Typeface tf = null;
        switch (font) {
            case RobotoLight:
                tf = Typeface.createFromAsset(mngr,"fonts/Roboto-Light.ttf");
                break;
            case RobotoThin:
                tf = Typeface.createFromAsset(mngr,"fonts/Roboto-Thin.ttf");
                break;
            case RobotoCondensedBold:
                tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Bold.ttf");
                break;
            case RobotoCondensedLight:
                tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Light.ttf");
                break;
            case RobotoCondensedRegular:
                tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Regular.ttf");
                break;
            default:
                tf = Typeface.DEFAULT;
                break;
        }
        return tf;
    }
    public void setupLayoutTypefaces(View v) {
        try {
            if (v instanceof ViewGroup) {
                ViewGroup vg = (ViewGroup) v;
                for (int i = 0; i < vg.getChildCount(); i++) {
                    View child = vg.getChildAt(i);
                    setupLayoutTypefaces(child);
                }
            } else if (v instanceof TextView) {
                if (v.getTag().toString().equals(AssetTypefaces.RobotoLight.toString())){
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoLight));
                }else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedRegular.toString())) {
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedRegular));
                }else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedBold.toString())) {
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedBold));
                }else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedLight.toString())) {
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedLight));
                }else if (v.getTag().toString().equals(AssetTypefaces.RobotoThin.toString())) {
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoThin));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            // ignore
        }
    }
}

In Ihrer Aktivität oder Ihrem Fragment rufen Sie einfach an

Fonts fonts = new Fonts(getActivity());
fonts.setupLayoutTypefaces(mainLayout);
4
majinboo

Ich denke, es kann einen einfacheren Weg geben. Die folgende Klasse legt ein benutzerdefiniertes Schriftbild für alle Komponenten Ihrer Anwendung fest (mit einer Einstellung pro Klasse).

/**
 * Base Activity of our app hierarchy.
 * @author SNI
 */
public class BaseActivity extends Activity {

    private static final String FONT_LOG_CAT_TAG = "FONT";
    private static final boolean ENABLE_FONT_LOGGING = false;

    private Typeface helloTypeface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        helloTypeface = Typeface.createFromAsset(getAssets(), "fonts/<your type face in assets/fonts folder>.ttf");
    }

    @Override
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        View view = super.onCreateView(name, context, attrs);
        return setCustomTypeFaceIfNeeded(name, attrs, view);
    }

    @Override
    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
        View view = super.onCreateView(parent, name, context, attrs);
        return setCustomTypeFaceIfNeeded(name, attrs, view);
    }

    protected View setCustomTypeFaceIfNeeded(String name, AttributeSet attrs, View view) {
        View result = null;
        if ("TextView".equals(name)) {
            result = new TextView(this, attrs);
            ((TextView) result).setTypeface(helloTypeface);
        }

        if ("EditText".equals(name)) {
            result = new EditText(this, attrs);
            ((EditText) result).setTypeface(helloTypeface);
        }

        if ("Button".equals(name)) {
            result = new Button(this, attrs);
            ((Button) result).setTypeface(helloTypeface);
        }

        if (result == null) {
            return view;
        } else {
            if (ENABLE_FONT_LOGGING) {
                Log.v(FONT_LOG_CAT_TAG, "A type face was set on " + result.getId());
            }
            return result;
        }
    }

}
3
Snicolas

Die Standardimplementierungen von LayoutInflater unterstützen die Angabe der Schriftartschriftart aus XML nicht. Ich habe es jedoch in xml gesehen, indem ich eine benutzerdefinierte Factory für den LayoutInflater zur Verfügung stellte, die solche Attribute aus dem XML-Tag analysiert.

Die Grundstruktur möchte dies.

public class TypefaceInflaterFactory implements LayoutInflater.Factory {

    @Override
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        // CUSTOM CODE TO CREATE VIEW WITH TYPEFACE HERE
        // RETURNING NULL HERE WILL TELL THE INFLATER TO USE THE
        // DEFAULT MECHANISMS FOR INFLATING THE VIEW FROM THE XML
    }

}

public class BaseActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LayoutInflater.from(this).setFactory(new TypefaceInflaterFactory());
    }
}

Dieser Artikel enthält eine ausführlichere Erklärung dieser Mechanismen und wie der Autor versucht, das XML-Layout auf diese Weise für Schriftarten bereitzustellen. Den Code für die Implementierung des Autors finden Sie hier .

2
Ryan Thomas

Ja, es ist möglich, indem die Standardschriftart überschrieben wird . Ich folgte der this -Lösung und es funktionierte mit einer einzigen Änderung auch für alle TextViews und ActionBar-Texte.

public class MyApp extends Application {

  @Override
  public void onCreate() {
    TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/Roboto-Regular.ttf"); // font from assets: "assets/fonts/Roboto-Regular.ttf
  }
}

styles.xml

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/pantone</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="Android:windowTranslucentStatus" tools:targetApi="KitKat">true</item>
    <item name="Android:windowDisablePreview">true</item>
    <item name="Android:typeface">serif</item>
</style>

Anstelle von themes.xml wie im obigen Link erwähnt, habe ich die Standardschriftart erwähnt, die in meinem styles.xml in meinem Standard-App-Design-Tag überschrieben werden soll. Die Standardschriftarten, die überschrieben werden können, sind Serifen, Sans, Monospace und Normal.

TypefaceUtil.Java

public class TypefaceUtil {

    /**
     * Using reflection to override default typeface
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN
     * @param context to work with assets
     * @param defaultFontNameToOverride for example "monospace"
     * @param customFontFileNameInAssets file name of the font from assets
     */
    public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) {
        try {
            final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets);

            final Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
            defaultFontTypefaceField.setAccessible(true);
            defaultFontTypefaceField.set(null, customFontTypeface);
        } catch (Exception e) {
            Log.e("Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
        }
    }
}

Anfangs wusste ich nicht, dass die zu überschreibenden Schriften fest sind und festgelegte Werte enthalten, aber es half mir schließlich zu verstehen, wie Android mit Schriften und Schriftarten und ihren Standardwerten umgeht, was ein anderer Punkt ist.

1
Amruta-Pani

Festlegen einer benutzerdefinierten Schriftart für einen regulären ProgressDialog/AlertDialog:

font=Typeface.createFromAsset(getAssets(),"DroidSans.ttf");

ProgressDialog dialog = ProgressDialog.show(this, "titleText", "messageText", true);
((TextView)dialog.findViewById(Resources.getSystem().getIdentifier("message", "id", "Android"))).setTypeface(font);
((TextView)dialog.findViewById(Resources.getSystem().getIdentifier("alertTitle", "id", "Android"))).setTypeface(font);
1
artProc

Arbeiten für Xamarin.Android:

Klasse:

public class FontsOverride
{
    public static void SetDefaultFont(Context context, string staticTypefaceFieldName, string fontAssetName)
    {
        Typeface regular = Typeface.CreateFromAsset(context.Assets, fontAssetName);
        ReplaceFont(staticTypefaceFieldName, regular);
    }

    protected static void ReplaceFont(string staticTypefaceFieldName, Typeface newTypeface)
    {
        try
        {
            Field staticField = ((Java.Lang.Object)(newTypeface)).Class.GetDeclaredField(staticTypefaceFieldName);
            staticField.Accessible = true;
            staticField.Set(null, newTypeface);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

Anwendungsimplementierung:

namespace SomeAndroidApplication
{
    [Application]
    public class App : Application
    {
        public App()
        {

        }

        public App(IntPtr handle, JniHandleOwnership transfer)
            : base(handle, transfer)
        {

        }

        public override void OnCreate()
        {
            base.OnCreate();

            FontsOverride.SetDefaultFont(this, "MONOSPACE", "fonts/Roboto-Light.ttf");
        }
    }
}

Stil:

<style name="Theme.Storehouse" parent="Theme.Sherlock">
    <item name="Android:typeface">monospace</item>
</style>
0
Guy Micciche

Es kann nützlich sein zu wissen, dass Sie ab Android 8.0 (API Level 26) eine benutzerdefinierte Schriftart in XML verwenden verwenden können.

Einfach ausgedrückt, können Sie dies auf folgende Weise tun.

  1. Legen Sie die Schriftart in den Ordner res/font.

  2. Verwenden Sie es entweder im Attribut eines Widgets 

<Button Android:fontFamily="@font/myfont"/>

oder lege es in res/values/styles.xml

<style name="MyButton" parent="Android:Widget.Button">
    <item name="Android:fontFamily">@font/myfont</item>
</style>

und benutze es als Stil

<Button style="@style/MyButton"/>
0
Vic

Ich mag den Vorschlag von Pospi. Verwenden Sie die Eigenschaft "Tag" einer Ansicht (die Sie in XML angeben können - "Android: Tag"), um alle zusätzlichen Einstellungen zu definieren, die Sie in XML nicht ausführen können. Ich mag JSON, also würde ich eine JSON-Zeichenfolge verwenden, um eine Schlüssel-/Wertemenge anzugeben. Diese Klasse erledigt die Arbeit - rufen Sie einfach Style.setContentView(this, [resource id]) in Ihrer Aktivität auf.

public class Style {

  /**
   * Style a single view.
   */
  public static void apply(View v) {
    if (v.getTag() != null) {
      try {
        JSONObject json = new JSONObject((String)v.getTag());
        if (json.has("typeface") && v instanceof TextView) {
          ((TextView)v).setTypeface(Typeface.createFromAsset(v.getContext().getAssets(),
                                                             json.getString("typeface")));
        }
      }
      catch (JSONException e) {
        // Some views have a tag without it being explicitly set!
      }
    }
  }

  /**
   * Style the passed view hierarchy.
   */
  public static View applyTree(View v) {
    apply(v);
    if (v instanceof ViewGroup) {
      ViewGroup g = (ViewGroup)v;
      for (int i = 0; i < g.getChildCount(); i++) {
        applyTree(g.getChildAt(i));
      }
    }
    return v;
  }

  /**
   * Inflate, style, and set the content view for the passed activity.
   */
  public static void setContentView(Activity activity, int resource) {
    activity.setContentView(applyTree(activity.getLayoutInflater().inflate(resource, null)));
  }
}

Natürlich möchten Sie nicht nur mit der Schrift umgehen, um die Verwendung von JSON sinnvoll zu machen. 

Ein Vorteil der Eigenschaft 'tag' besteht darin, dass Sie sie auf einen Basisstil setzen können, den Sie als Design verwenden, und ihn somit automatisch auf alle Ihre Ansichten anwenden lassen. BEARBEITEN: Dies führt bei Android 4.0.3 zu einem Absturz während der Inflation. Sie können weiterhin einen Stil verwenden und ihn einzeln auf Textansichten anwenden.

Eine Sache, die Sie im Code sehen werden - einige Ansichten haben ein Tag, ohne dass eines explizit gesetzt wird - bizarr ist es die Zeichenfolge "Αποκοπή" - die auf Griechisch "geschnitten" ist, gemäß Google Translate! Was zur Hölle...?

0
Richard

Die Antwort von @majinboo wurde hinsichtlich Performance- und Speichermanagement überarbeitet. Für mehrere Schriftarten, für die eine Aktivität erforderlich ist, kann Activity diese Schriftklasse verwenden, indem sie den Konstruktor selbst als Parameter angeben.

@Override
public void onCreate(Bundle savedInstanceState)
{
    Font font = new Font(this);
}

Die überarbeitete Schriftklasse ist wie folgt:

public class Fonts
{
    private HashMap<AssetTypefaces, Typeface> hashMapFonts;

    private enum AssetTypefaces
    {
        RobotoLight,
        RobotoThin,
        RobotoCondensedBold,
        RobotoCondensedLight,
        RobotoCondensedRegular
    }

    public Fonts(Context context)
    {
        AssetManager mngr = context.getAssets();

        hashMapFonts = new HashMap<AssetTypefaces, Typeface>();
        hashMapFonts.put(AssetTypefaces.RobotoLight, Typeface.createFromAsset(mngr, "fonts/Roboto-Light.ttf"));
        hashMapFonts.put(AssetTypefaces.RobotoThin, Typeface.createFromAsset(mngr, "fonts/Roboto-Thin.ttf"));
        hashMapFonts.put(AssetTypefaces.RobotoCondensedBold, Typeface.createFromAsset(mngr, "fonts/RobotoCondensed-Bold.ttf"));
        hashMapFonts.put(AssetTypefaces.RobotoCondensedLight, Typeface.createFromAsset(mngr, "fonts/RobotoCondensed-Light.ttf"));
        hashMapFonts.put(AssetTypefaces.RobotoCondensedRegular, Typeface.createFromAsset(mngr, "fonts/RobotoCondensed-Regular.ttf"));
    }

    private Typeface getTypeface(String fontName)
    {
        try
        {
            AssetTypefaces typeface = AssetTypefaces.valueOf(fontName);
            return hashMapFonts.get(typeface);
        }
        catch (IllegalArgumentException e)
        {
            // e.printStackTrace();
            return Typeface.DEFAULT;
        }
    }

    public void setupLayoutTypefaces(View v)
    {
        try
        {
            if (v instanceof ViewGroup)
            {
                ViewGroup vg = (ViewGroup) v;
                for (int i = 0; i < vg.getChildCount(); i++)
                {
                    View child = vg.getChildAt(i);
                    setupLayoutTypefaces(child);
                }
            }
            else if (v instanceof TextView)
            {
                ((TextView) v).setTypeface(getTypeface(v.getTag().toString()));
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            // ignore
        }
    }
}
0
Suphi ÇEVİKER

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

Es sieht so aus, als wäre die Verwendung von benutzerdefinierten Schriftarten mit Android O leicht gemacht worden. Grundsätzlich können Sie XML verwenden, um dies zu erreichen. Ich habe einen Link zur offiziellen Dokumentation von Android als Referenz beigefügt, und hoffentlich hilft dies Menschen, die diese Lösung noch benötigen. Mit benutzerdefinierten Schriftarten in Android arbeiten

0
Mohale