Android 在TextView上应用字体系列

Android 在TextView上应用字体系列,android,textview,Android,Textview,我是Android新手。在我的应用程序中,我有许多TextView,我想在TextView上应用不同的字体系列,并附带以下条件的编号: 1: TextView should never be extend i.e I don't want to create my custom Textview 2: I don't want to set the font on run time i.e First get the reference of textview in code then set

我是Android新手。在我的应用程序中,我有许多TextView,我想在TextView上应用不同的字体系列,并附带以下条件的编号:

1: TextView should never be extend i.e I don't want to create my custom Textview
2: I don't want to set the font on run time i.e First get the reference of textview in code then set programmitically  by using the setType method.
3: I just want to do with the XML tag like "customeFontFamily" and for this tag i can provide different font family on different TextView.
我也读过,但它显示了第一个android默认字体系列。500毫秒后,它更改了我在XML中定义的字体系列

在此问题上的任何帮助都将不胜感激!提前谢谢你

我建议使用。这是定制字体的最佳解决方案。它在运行时设置字体。

我建议使用。这是定制字体的最佳解决方案。它在运行时设置字体。

您的要求:

1:我不想通过扩展Textview来创建自定义Textview

2:我不想在运行时设置字体

3:我只想使用自定义XML属性,如customFontFamily

在这些要求下,您的问题没有解决方案

Android SDK中的所有视图都没有处理您定义的任何自定义XML属性的代码。如果要使用自定义XML属性,则必须将TextView子类化。如果您没有子类TextView,那么您别无选择,只能在运行时设置字体。仅此而已。

您的要求:

1:我不想通过扩展Textview来创建自定义Textview

2:我不想在运行时设置字体

3:我只想使用自定义XML属性,如customFontFamily

在这些要求下,您的问题没有解决方案


Android SDK中的所有视图都没有处理您定义的任何自定义XML属性的代码。如果要使用自定义XML属性,则必须将TextView子类化。如果您没有子类TextView,那么您别无选择,只能在运行时设置字体。这就是它的全部内容。

您可能正在寻找这个

此属性android:fontFamily允许您设置项目或系统中的fontFamily

如果您想以编程方式执行,我读到您不想要它,但将来可能可以检查setTypeface方法


也许你在找这个

此属性android:fontFamily允许您设置项目或系统中的fontFamily

如果您想以编程方式执行,我读到您不想要它,但将来可能可以检查setTypeface方法


我找到了通过XML标记更改字体系列的方法。我创建了自定义工厂类来实现这一点。这是:

步骤1:创建类MyFontFactory并将此代码放入此类中

public class MyFontFactory implements LayoutInflater.Factory2 {

    private static final String DEFAULT_FONT_FAMILY = "HelveticaLTStd-Roman"; // default application font
    private static final String[] extensions = {"ttf", "otf"};
    private static final String[] classPrefixes = {"android.widget.", "android.webkit.", "android.view."};
    private static MyFontFactory instance;
    private final LinkedList<String> fontFamilies = new LinkedList<String>();
    private final HashMap<String, Typeface> cache = new HashMap<String, Typeface>(16);

    private MyFontFactory() {}

    public static MyFontFactory getInstance() {
        return instance != null ? instance : (instance = new MyFontFactory());
    }

    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
        return createView(name, context, attrs);
    }

    public View onCreateView(String name, Context context, AttributeSet attrs) {
        return createView(name, context, attrs);
    }

    public static void attachFragment(Activity activity) {
        attachToFactory(activity.getLayoutInflater());
    }

    public static void attachDialog(Dialog dialog) { 
        attachToFactory(dialog.getLayoutInflater());
    }

    public static void attachToFactory(LayoutInflater li) {
        if (!(li.getFactory2() instanceof MyFontFactory) && !(li.getFactory() instanceof MyFontFactory)) {
            li.setFactory2(getInstance());
        }
    }

    public static void pushFont(String defaultFontFamily) {
        getInstance().fontFamilies.addFirst(defaultFontFamily);
    }

    public static void popFont() {
        getInstance().fontFamilies.removeFirst();
    }

    private View createView(String name, Context context, AttributeSet attrs) {
        View v = !name.contains(".") ? null : create(name, null, context, attrs);
        if (v == null) {
            for (String prefix : classPrefixes) {
                v = create(name, prefix, context, attrs);
                if (v != null) {
                    break;
                }
            }
        }
        return setFontFamily(v, context, attrs);
    }

    private static View create(String name, String prefix, Context context, AttributeSet attrs) {
        try {
            return LayoutInflater.from(context).createView(name, prefix, attrs);
        } catch (Throwable e) { 
            e.printStackTrace();
            return null;
        }
    }

    public View setFontFamily(final View v, final Context context, AttributeSet attrs) {
        if (context.getTheme() != null && v instanceof TextView && !v.isInEditMode()) {
            TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.TextView, 0, 0);
            try {
                final String ff = resolveFontFamily(
                        a != null ? a.getString(R.styleable.TextView_fontFamily) : null, context);
                final Typeface typeface = loadTypeface(context, ff);
                if (typeface != null) {
                    ((TextView)v).setTypeface(typeface);
                }
            } finally {
                if (a != null) { a.recycle(); }
            }
        }
        return v;
    }

    private String resolveFontFamily(String ff, Context context) {
        if (ff == null && !fontFamilies.isEmpty()) {
            ff = fontFamilies.getFirst();
        }
        if (ff == null) {
            ff = context.getResources().getString(R.string.DEFAULT_FONT_FAMILY);
        }
        if (ff == null) {
            ff = DEFAULT_FONT_FAMILY;
        }
        return ff;
    }

    private Typeface loadTypeface(Context context, String fontFamily) {
        if (TextUtils.isEmpty(fontFamily)) {
            return null;
        }
        Typeface typeface = cache.get(fontFamily);
        if (typeface == null) {
            for (String ext : extensions) {
                try {
                    typeface = Typeface.createFromAsset(context.getAssets(), String.format("fonts/%s.%s", fontFamily, ext));
                } catch (Throwable t) {
                    // ignore
                }
            }
        }
        if (typeface != null) {
            cache.put(fontFamily, typeface);
        }
        return typeface;
    }
}
步骤3:在自定义标记attrs.XML的值下创建任何XML,并将这些行放在此文件下

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

  <declare-styleable name="TextView" >
    <attr name="fontFamily" format="string"/>
  </declare-styleable>

</resources>
步骤4:只需创建一个包含任何textview的布局,并将其设置为xml标记

android:fontFamily = "@String/helveticafont"

and create any tag under String.xml says <String name =helveticafont>HelveticaLTStd-Roman</>
步骤5:将字体文件放在资产->字体下,然后放在任何支持的扩展文件下

步骤6:现在用FounderActivity代替activity扩展所有应用程序活动。
这就是我所做的。

我找到了通过XML标记更改字体系列的方法。我创建了自定义工厂类来实现这一点。这是:

步骤1:创建类MyFontFactory并将此代码放入此类中

public class MyFontFactory implements LayoutInflater.Factory2 {

    private static final String DEFAULT_FONT_FAMILY = "HelveticaLTStd-Roman"; // default application font
    private static final String[] extensions = {"ttf", "otf"};
    private static final String[] classPrefixes = {"android.widget.", "android.webkit.", "android.view."};
    private static MyFontFactory instance;
    private final LinkedList<String> fontFamilies = new LinkedList<String>();
    private final HashMap<String, Typeface> cache = new HashMap<String, Typeface>(16);

    private MyFontFactory() {}

    public static MyFontFactory getInstance() {
        return instance != null ? instance : (instance = new MyFontFactory());
    }

    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
        return createView(name, context, attrs);
    }

    public View onCreateView(String name, Context context, AttributeSet attrs) {
        return createView(name, context, attrs);
    }

    public static void attachFragment(Activity activity) {
        attachToFactory(activity.getLayoutInflater());
    }

    public static void attachDialog(Dialog dialog) { 
        attachToFactory(dialog.getLayoutInflater());
    }

    public static void attachToFactory(LayoutInflater li) {
        if (!(li.getFactory2() instanceof MyFontFactory) && !(li.getFactory() instanceof MyFontFactory)) {
            li.setFactory2(getInstance());
        }
    }

    public static void pushFont(String defaultFontFamily) {
        getInstance().fontFamilies.addFirst(defaultFontFamily);
    }

    public static void popFont() {
        getInstance().fontFamilies.removeFirst();
    }

    private View createView(String name, Context context, AttributeSet attrs) {
        View v = !name.contains(".") ? null : create(name, null, context, attrs);
        if (v == null) {
            for (String prefix : classPrefixes) {
                v = create(name, prefix, context, attrs);
                if (v != null) {
                    break;
                }
            }
        }
        return setFontFamily(v, context, attrs);
    }

    private static View create(String name, String prefix, Context context, AttributeSet attrs) {
        try {
            return LayoutInflater.from(context).createView(name, prefix, attrs);
        } catch (Throwable e) { 
            e.printStackTrace();
            return null;
        }
    }

    public View setFontFamily(final View v, final Context context, AttributeSet attrs) {
        if (context.getTheme() != null && v instanceof TextView && !v.isInEditMode()) {
            TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.TextView, 0, 0);
            try {
                final String ff = resolveFontFamily(
                        a != null ? a.getString(R.styleable.TextView_fontFamily) : null, context);
                final Typeface typeface = loadTypeface(context, ff);
                if (typeface != null) {
                    ((TextView)v).setTypeface(typeface);
                }
            } finally {
                if (a != null) { a.recycle(); }
            }
        }
        return v;
    }

    private String resolveFontFamily(String ff, Context context) {
        if (ff == null && !fontFamilies.isEmpty()) {
            ff = fontFamilies.getFirst();
        }
        if (ff == null) {
            ff = context.getResources().getString(R.string.DEFAULT_FONT_FAMILY);
        }
        if (ff == null) {
            ff = DEFAULT_FONT_FAMILY;
        }
        return ff;
    }

    private Typeface loadTypeface(Context context, String fontFamily) {
        if (TextUtils.isEmpty(fontFamily)) {
            return null;
        }
        Typeface typeface = cache.get(fontFamily);
        if (typeface == null) {
            for (String ext : extensions) {
                try {
                    typeface = Typeface.createFromAsset(context.getAssets(), String.format("fonts/%s.%s", fontFamily, ext));
                } catch (Throwable t) {
                    // ignore
                }
            }
        }
        if (typeface != null) {
            cache.put(fontFamily, typeface);
        }
        return typeface;
    }
}
步骤3:在自定义标记attrs.XML的值下创建任何XML,并将这些行放在此文件下

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

  <declare-styleable name="TextView" >
    <attr name="fontFamily" format="string"/>
  </declare-styleable>

</resources>
步骤4:只需创建一个包含任何textview的布局,并将其设置为xml标记

android:fontFamily = "@String/helveticafont"

and create any tag under String.xml says <String name =helveticafont>HelveticaLTStd-Roman</>
步骤5:将字体文件放在资产->字体下,然后放在任何支持的扩展文件下

步骤6:现在用FounderActivity代替activity扩展所有应用程序活动。
这就是我所做的。

我还提到了上面的一个链接,它满足了我的要求,但我在500毫秒后得到了确切的字体系列。你能检查一下上面提到的链接吗。并建议我该怎么做。链接到我们可以阅读的东西,而不是我们必须执行的东西。2.解释500毫秒背后的上下文。这是性能问题还是其他问题?500毫秒背后的背景是,我有一个带有文本视图编号的活动,当我运行我的应用程序时,它会在屏幕上显示android的默认字体系列,几次后,它会显示自定义字体系列,以便用户很容易注意到字体已更改@karakuriTry更快地加载字体,例如,一旦创建应用程序并缓存它。我还提到了上面的一个链接,它满足了我的要求,但我在500毫秒后得到了确切的字体系列。你能检查一下上面提到的链接吗。并建议我该怎么做。链接到我们可以阅读的东西,而不是我们必须执行的东西。2.解释500毫秒背后的上下文。这是性能问题还是其他问题?500毫秒背后的背景是,我有一个带有文本视图编号的活动,当我运行我的应用程序时,它会在屏幕上显示android的默认字体系列,几次后,它会显示自定义字体系列,以便用户很容易注意到字体已更改@karakuriTry很快就会加载字体
呃,例如,创建应用程序并缓存它。我在代码中使用了书法库,但收到一个错误,即找不到支持的库。v7.widget.Toolbar。他在书法工厂课程的代码中使用了这个库。从哪里可以找到包含Toolbar类的support-v7库?我很确定com.android.support:appcompat-v7:21.0.0有Toolbar类。不,我有相同的库,但它不包含Toolbar类。这不是一个错误,而是一个警告。我们检查该类的类路径。你可以忽略它们。只是达尔维克/阿特在抱怨。如果没有OKHttp,其他LIB也会这样做,比如改型/Picasso。我在代码中使用了书法库,但出现了一个错误,即找不到支持的库。v7.widget.Toolbar。他在书法工厂课程的代码中使用了这个库。从哪里可以找到包含Toolbar类的support-v7库?我很确定com.android.support:appcompat-v7:21.0.0有Toolbar类。不,我有相同的库,但它不包含Toolbar类。这不是一个错误,而是一个警告。我们检查该类的类路径。你可以忽略它们。只是达尔维克/阿特在抱怨。如果您没有OKHttp,其他LIB也会这样做,例如翻新/Picasso。