【问题标题】:Custom Fonts and Custom Textview on AndroidAndroid 上的自定义字体和自定义文本视图
【发布时间】:2012-01-21 16:11:23
【问题描述】:

从我需要开发的应用程序中,我收到了包含许多文件的特定字体,例如 FontName-Regular、FontName-BoldFontName-it。我需要在应用程序的所有文本视图中使用它。首先,我认为这是一项简单的任务。翻看SO,发现一个很不错的线程:here

所以首先我确实喜欢:

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

并在我的活动中的 onCreate 期间调用了此方法。我的应用程序中的每个 textView 都显示了那个字体和男孩,我很高兴能如此轻松地离开。直到我进入一个屏幕,其中一些文本视图需要 Bold 作为Style (android:textStyle="bold")。然后我意识到这个解决方案不能让我从资产中加载 Font-Bold.ttf。

在同一个 SO 问题中,进一步查看并看到了一个不错的自定义 TextView 实现:

public class MyTextView extends TextView {

    public MyTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MyTextView(Context context) {
        super(context);
        init();
    }

    public void init() {

        Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "font/chiller.ttf");
        setTypeface(tf ,1);

    }
    }

这看起来更好。我的问题是:如何在init() 上检测我的控件是否将 Style 设置为 Bold 以便我可以分配请求的 TypeFace ?

感谢您的宝贵时间。

乐。按照下面的示例,我将我的课程更新为:

public class MyTextView extends TextView {

    Typeface normalTypeface = Typeface.createFromAsset(getContext().getAssets(), Constants.FONT_REGULAR);
    Typeface boldTypeface = Typeface.createFromAsset(getContext().getAssets(),  Constants.FONT_BOLD);

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

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

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

    public void setTypeface(Typeface tf, int style) {
        if (style == Typeface.BOLD) {
            super.setTypeface(boldTypeface/*, -1*/);
        } else {
            super.setTypeface(normalTypeface/*, -1*/);
        }
    }
}

好吧,如果我调试,应用程序进入 setTypeFace 并且它似乎应用了粗体,但在我的布局上我看不到任何变化,而不是粗体。无论我使用什么字体,我的 TextView 都不会进行任何更改,并使用默认的 android 字体显示。我想知道为什么?

我已经在一篇博文here on my blog 上总结了所有内容,也许它会对某人有所帮助。

【问题讨论】:

  • 感谢您提供详细的问题和详细说明,以及精彩的博文!非常适合我。我还将 Button 子类化以获得相同的结果。我唯一的查询是 w.r.t. 每次调用 createFromAsset() 的效率。加载一次字体并将它们存储在您的应用程序类中,然后从 MyTextView.setTypeface() 访问这些字体会更好吗?
  • 感谢您的发言。我也想过这个问题,但没有测试看看它是如何工作的或是否有效。它应该可以正常工作。无论如何,我还没有看到屏幕上有很多视图会降低性能。

标签: android custom-controls textview typeface


【解决方案1】:

TextView 的构造函数使用从 XML 属性 android:textStyle 检索到的 style 参数调用 setTypeface(Typeface tf, int style)。因此,如果您想拦截此调用以强制使用您自己的字体,您可以重写此方法,如下所示:

public void setTypeface(Typeface tf, int style) {
    Typeface normalTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/your_normal_font.ttf");
    Typeface boldTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/your_bold_font.ttf");

    if (style == Typeface.BOLD) {
        super.setTypeface(boldTypeface/*, -1*/);
    } else {
        super.setTypeface(normalTypeface/*, -1*/);
    }
}

【讨论】:

  • @Alin:问题是setTypeface()Typefaces 被创建之前就被构造函数调用了!所以,将Typefaces 的创建移到setTypeface() 中,现在它可以工作了!
  • 我尝试使用相同的解决方案,但不知何故,它调用了 setType(Typeface tf) 而不是 setTypeface(Typeface tf, int style),并且它被调用了两次。我必须进行一些更改以确保保留粗体和斜体样式。无论如何,这给了我正确的方向,它现在有效。谢谢。
【解决方案2】:

您可以使用我的CustomTextView,它允许您在assets 文件夹中指定字体文件名:

https://github.com/mafshin/CustomTextView

而且用法很简单:

<com.my.app.CustomTextView
        xmlns:custom="http://schemas.android.com/apk/res/com.my.app"            
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test text"
        android:id="@+id/testcustomview" 

        custom:fontAssetName="Politica XT.otf"
        />

【讨论】:

    【解决方案3】:

    我认为最好为自定义字体创建自己的包并将它们导入您的项目中,以便您以后可以使用它们

      package com.codeslips.utilities;  
    
      import android.content.Context; 
      import android.graphics.Typeface;
      import android.util.AttributeSet;
      import android.widget.TextView;  
    
      public class CustomTextView extends TextView {  
    
              public CustomTextView(Context context)
                   { super(context); setFont(); }  
    
              public CustomTextView(Context context,AttributeSet set)
                 { super(context,set); setFont(); } 
    
              public CustomTextView(Context context,AttributeSet set,int defaultStyle) 
                 { super(context,set,defaultStyle); setFont(); } 
    
              private void setFont() { 
    
               Typeface typeface=Typeface.createFromAsset(getContext().getAssets(),"fonts/your-font.ttf"); 
               setTypeface(typeface); //function used to set font
    
                 }  
              }
    

    现在在你的 XML 文件中使用上面的类来拥有你的自定义字体

        <com.codeslips.utilities.CustomTextView   
           android:layout_width="wrap_content" 
           android:layout_height="match_parent"
           android:text="Upload Image" 
           android:paddingTop="10sp"
           android:textSize="14sp"
           android:layout_weight="0.7"
           android:textColor="@android:color/white"/>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-22
      • 2013-02-23
      • 2011-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-03
      • 1970-01-01
      相关资源
      最近更新 更多