Java 自定义字体和 XML 布局 (Android)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2376250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 06:43:19  来源:igfitidea点击:

Custom fonts and XML layouts (Android)

javaandroiduser-interfaceinterfacefonts

提问by DrDefrost

I'm trying to define a GUI layout using XML files in Android. As far as I can find out, there is no way to specify that your widgets should use a custom font (e.g. one you've placed in assets/font/) in XML files and you can only use the system installed fonts.

我正在尝试使用 Android 中的 XML 文件定义 GUI 布局。据我所知,没有办法指定您的小部件应该在 XML 文件中使用自定义字体(例如,您放置在 assets/font/ 中的字体),并且您只能使用系统安装的字体。

I know that, in the Java code, I could change the font of each widget manually using unique IDs. Alternatively, I could iterate over all the widgets in Java to make this change, but this would probably be very slow.

我知道,在 Java 代码中,我可以使用唯一 ID 手动更改每个小部件的字体。或者,我可以遍历 Java 中的所有小部件以进行此更改,但这可能会非常慢。

What other options do I have? Is there any better ways to making widgets that have a custom look? I don't particularly want to have to manually change the font for every new widget I add.

我还有什么其他选择?有没有更好的方法来制作具有自定义外观的小部件?我并不特别想为我添加的每个新小部件手动更改字体。

回答by Tareq Sha

The only way to use custom fonts is through the source code.

使用自定义字体的唯一方法是通过源代码。

Just remember that Android runs on devices with very limited resources and fonts might require a good amount of RAM. The built-in Droid fonts are specially made and, if you note, have many characters and decorations missing.

请记住,Android 在资源非常有限的设备上运行,字体可能需要大量 RAM。内置的 Droid 字体是特制的,如果您注意到,缺少许多字符和装饰。

回答by Nathan Schwermann

Extend TextViewand give it a custom attribute or just use the android:tag attribute to pass in a String of what font you want to use. You will need to pick a convention and stick to it such as I will put all of my fonts in the res/assets/fonts/ folder so your TextView class knows where to find them. Then in your constructor you just set the font manually after the super call.

扩展TextView并给它一个自定义属性,或者只使用 android:tag 属性传入一个你想要使用的字体的字符串。您需要选择一个约定并坚持下去,例如我会将所有字体放在 res/assets/fonts/ 文件夹中,以便您的 TextView 类知道在哪里可以找到它们。然后在您的构造函数中,您只需在 super 调用后手动设置字体。

回答by Carl Whalley

You can't extend TextView to create a widget or use one in a widgets layout: http://developer.android.com/guide/topics/appwidgets/index.html

你不能扩展 TextView 来创建一个小部件或在小部件布局中使用一个:http: //developer.android.com/guide/topics/appwidgets/index.html

回答by peter

You can extend TextView to set custom fonts as I learned here.

您可以扩展 TextView 以设置自定义字体,正如我在此处学到的。

TextViewPlus.java:

TextViewPlus.java:

package com.example;

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

public class TextViewPlus extends TextView {
    private static final String TAG = "TextView";

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

    public TextViewPlus(Context context, AttributeSet attrs) {
        super(context, attrs);
        setCustomFont(context, attrs);
    }

    public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setCustomFont(context, attrs);
    }

    private void setCustomFont(Context ctx, AttributeSet attrs) {
        TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus);
        String customFont = a.getString(R.styleable.TextViewPlus_customFont);
        setCustomFont(ctx, customFont);
        a.recycle();
    }

    public boolean setCustomFont(Context ctx, String asset) {
        Typeface tf = null;
        try {
        tf = Typeface.createFromAsset(ctx.getAssets(), asset);  
        } catch (Exception e) {
            Log.e(TAG, "Could not get typeface: "+e.getMessage());
            return false;
        }

        setTypeface(tf);  
        return true;
    }

}

attrs.xml:(in res/values)

attrs.xml:(在资源/值中)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="TextViewPlus">
        <attr name="customFont" format="string"/>
    </declare-styleable>
</resources>

main.xml:

主文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:foo="http://schemas.android.com/apk/res/com.example"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.example.TextViewPlus
        android:id="@+id/textViewPlus1"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:text="@string/showingOffTheNewTypeface"
        foo:customFont="saxmono.ttf">
    </com.example.TextViewPlus>
</LinearLayout>

You would put "saxmono.ttf" in the assetsfolder.

您可以将“saxmono.ttf”放在资产文件夹中。

UPDATE 8/1/13

更新 8/1/13

There are serious memory concerns with this method. See chedabob's commentbelow.

这种方法存在严重的内存问题。请参阅下面的chedabob 评论

回答by browep

Here's a tutorial that shows you how to setup a custom font like @peter described: http://responsiveandroid.com/2012/03/15/custom-fonts-in-android-widgets.html

这是一个教程,向您展示如何设置像@peter 描述的自定义字体:http://responsiveandroid.com/2012/03/15/custom-fonts-in-android-widgets.html

it also has consideration for potential memory leaks ala http://code.google.com/p/android/issues/detail?id=9904. Also in the tutorial is an example for setting a custom font on a button.

它还考虑了潜在的内存泄漏 ala http://code.google.com/p/android/issues/detail?id=9904。本教程中还有一个在按钮上设置自定义字体的示例。

回答by Tore Rudberg

If you only have one typeface you would like to add, and want less code to write, you can create a dedicated TextView for your specific font. See code below.

如果您只想添加一种字体,并且希望编写更少的代码,您可以为您的特定字体创建一个专用的 TextView。请参阅下面的代码。

package com.yourpackage;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;

public class FontTextView extends TextView {
    public static Typeface FONT_NAME;


    public FontTextView(Context context) {
        super(context);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
    public FontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
    public FontTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
}

In main.xml, you can now add your textView like this:

在 main.xml 中,您现在可以像这样添加 textView:

<com.yourpackage.FontTextView
    android:id="@+id/tvTimer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="" />

回答by Jelle

Peter's answer is the best, but it can be improved by using the styles.xml from Android to customize your fonts for all textviews in your app.

彼得的答案是最好的,但可以通过使用来自 Android 的 style.xml 为应用程序中的所有文本视图自定义字体来改进它。

My code is here

我的代码在这里

回答by Leonardo Cardoso

This might be a little late, but you need to create a singleton class that returns the custom typeface to avoid memory leaks.

这可能有点晚了,但您需要创建一个返回自定义字体的单例类以避免内存泄漏。

TypeFace class:

字体类:

public class OpenSans {

private static OpenSans instance;
private static Typeface typeface;

public static OpenSans getInstance(Context context) {
    synchronized (OpenSans.class) {
        if (instance == null) {
            instance = new OpenSans();
            typeface = Typeface.createFromAsset(context.getResources().getAssets(), "open_sans.ttf");
        }
        return instance;
    }
}

public Typeface getTypeFace() {
    return typeface;
}
}

Custom TextView:

自定义文本视图:

public class NativelyCustomTextView extends TextView {

    public NativelyCustomTextView(Context context) {
        super(context);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

    public NativelyCustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

    public NativelyCustomTextView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

}

By xml:

通过 xml:

<com.yourpackage.views.NativelyCustomTextView
            android:id="@+id/natively_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_margin="20dp"
            android:text="@string/natively"
            android:textSize="30sp" /> 

Programmatically:

以编程方式:

TextView programmaticallyTextView = (TextView) 
       findViewById(R.id.programmatically_text_view);

programmaticallyTextView.setTypeface(OpenSans.getInstance(this)
                .getTypeFace());

回答by Ragunath Jawahar

I'm 3 years late for the party :( However this could be useful for someone who might stumble upon this post.

我参加聚会晚了 3 年 :( 但是这对于可能偶然发现这篇文章的人可能很有用。

I've written a library that caches Typefaces and also allow you to specify custom typefaces right from XML. You can find the library here.

我编写了一个缓存字体的库,还允许您直接从 XML 指定自定义字体。你可以在这里找到图书馆。

Here is how your XML layout would look like, when you use it.

这是您使用 XML 布局时的样子。

<com.mobsandgeeks.ui.TypefaceTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world"
    geekui:customTypeface="fonts/custom_font.ttf" />

回答by San

I might have a simple answer for the question without extending the TextView and implementing a long code.

我可能对这个问题有一个简单的答案,而无需扩展 TextView 并实现长代码。

Code :

代码 :

 TextView tv = (TextView) findViewById(R.id.textview1);
    tv.setTypeface(Typeface.createFromAsset(getAssets(), "font.ttf"));

Place the custom font file in assets folder as usual and try this. It works for me. I just dont understand why peter has given such a huge code for this simple thing or he has given his answer in old version.

像往常一样将自定义字体文件放在 assets 文件夹中,然后试试这个。这个对我有用。我只是不明白为什么彼得为这个简单的事情提供了如此庞大的代码,或者他在旧版本中给出了答案。