111 Stimmen

Verwendung einer benutzerdefinierten Schriftart in Android

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

Also,

  • Gibt es eine Möglichkeit, dies über die XML-Datei zu tun? [Einstellung einer benutzerdefinierten Schriftart]
  • Gibt es eine Möglichkeit, dies vom Code aus an einer Stelle zu tun, um zu sagen, dass die gesamte Anwendung und alle Komponenten die benutzerdefinierte Schriftart anstelle der Standardschriftart verwenden sollen?

10voto

Informatic0re Punkte 6180

Hey ich brauche auch 2 verschiedene Schriftarten in meiner App für verschiedene Breiten! Ich benutze diesen Weg:

In meiner Anwendungsklasse 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 typeface repräsentiert die xyz.ttf im Asset-Ordner. (ich habe eine Konstantenklasse erstellt) Jetzt können Sie dies überall in Ihrer Anwendung verwenden:

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

Das Problem ist nur, dass Sie dies für jedes Widget brauchen, in dem Sie die Schriftart verwenden wollen! Aber ich denke, das ist der beste Weg.

4voto

userM1433372 Punkte 5145

Ich habe eine gute Lösung gefunden auf der Blog von Lisa Wray . 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"/>

4voto

majinboo Punkte 181

Verwendung von Pospis Vorschlag und arbeiten mit der Eigenschaft "tag" wie Richard tat, habe ich eine benutzerdefinierte Klasse erstellt, die meine benutzerdefinierten Schriftarten lädt und sie auf die Ansichten entsprechend ihrer Tags anwendet.

Anstatt also die TypeFace im Attribut Android:fontFamily zu setzen, verwenden Sie das Android:tag-Attribut und setzen es auf eine 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 Activity oder Ihrem Fragment rufen Sie einfach

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

3voto

Snicolas Punkte 37333

Ich denke, es gibt einen einfacheren Weg, dies zu tun. Die folgende Klasse wird eine benutzerdefinierte Art Gesicht für alle Ihre Komponenten Ihrer Anwendung (mit einer Einstellung pro Klasse) festgelegt.

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

}

2voto

Ryan Thomas Punkte 479

Die Standardimplementierungen von LayoutInflater unterstützen die Angabe der Schriftart aus xml nicht. Ich habe jedoch gesehen, es in xml getan, indem Sie eine benutzerdefinierte Fabrik für die LayoutInflater, die solche Attribute aus dem xml-Tag analysiert wird.

Die Grundstruktur sieht folgendermaßen aus.

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 bietet eine ausführlichere Erklärung dieser Mechanismen und wie der Autor versucht, auf diese Weise xml-Layout-Unterstützung für Schriften zu bieten. Der Code für die Implementierung des Autors kann gefunden werden aquí .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X