在TextView上应用字体系列

时间:2014-11-13 15:44:17

标签: android textview

我是Android新手。在我的应用程序中,我有许多TextViews,我想在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.

我也阅读了this link,但它显示了第一个Android默认字体系列。 500 mili秒后,它会更改我在XML中定义的字体系列。

对此问题的任何帮助将不胜感激!先感谢您!

4 个答案:

答案 0 :(得分:2)

您的要求:

  

1:我不想通过扩展TextView

来创建自定义Textview      

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

     

3:我只想使用“customFontFamily”等自定义XML属性

根据这些要求,您的问题无法解决。

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

我找到了通过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;
    }
}

第2步:现在创建一个Activity,说FounderActivity随Activity一起扩展,并放在此Activity的代码下面。

public class FounderActivity extends Activity {

    public void onCreate(android.os.Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getLayoutInflater().setFactory2(MyFontFactory.getInstance());
    }

    public void setContentView(int id) {
        View v = LayoutInflater.from(this).inflate(id, null);
        super.setContentView(v);
    }

    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
        View v = super.onCreateView(parent, name, context, attrs);
        if (v == null) {
            MyFontFactory.getInstance().onCreateView(parent, name, context, attrs);
        }
        if (v != null) {
            MyFontFactory.getInstance().setFontFamily(v, context, attrs);
        }
        return v;
    }}

步骤3:在自定义标记的值下创建任何XML,如attrs.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步:将字体文件放在资源下 - &gt;字体然后任何支持的扩展文件。

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

答案 3 :(得分:0)

可能你正在寻找这个

http://developer.android.com/reference/android/widget/TextView.html#attr_android:fontFamily

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

如果您想以编程方式执行此操作(我读过您不想要,但可能在将来),您可以查看setTypeface()方法。

http://developer.android.com/reference/android/widget/TextView.html#setTypeface(android.graphics.Typeface)