【问题标题】:Make a public type face method in Android在Android中制作公共字体方法
【发布时间】:2016-08-29 06:51:50
【问题描述】:

我正在尝试在不同的Activities 中应用自定义字体,现在我在MainActivityonCreate() 中有以下代码:

String fontTitle = "fonts/OpenSans-Bold.ttf";
Typeface titleFont = Typeface.createFromAsset(getAssets(), fontTitle);
page_title.setTypeface(titleFont);

我想知道是否可以将Typeface 公开,以便我可以在其他活动中访问它。

我创建了一个名为FontHelper的类:

public class FontHelper extends MainActivity {

    // path for the fonts
    String fontTitle = "fonts/OpenSans-Bold.ttf";

    Typeface titleFont = Typeface.createFromAsset(getAssets(), fontTitle);

}

但在其他Activities 中,当我使用textView.setTypeface(FontHelper.titleFont) 时出现错误。我该如何解决这个错误?

【问题讨论】:

  • 在每个 Activity 中创建一个新的 Typeface 实例有什么问题?还是创建字体的静态工厂方法?您尝试做的事情在技术上是可行的,但只会造成内存泄漏 - 我希望您知道这是一件坏事。
  • @XaverKapeller 我想在不同的活动中使用字体,但我认为它是多余的,所以我决定创建一个辅助类。这如何造成内存泄漏?我刚刚在最后一个示例中阅读了this post,它有点像我想要的那样,这还会造成内存泄漏吗?
  • 是的,不要盲目跟随互联网上的随机博客帖子。拥有一个帮助类并不是一件坏事,但是这篇文章中帮助类的实现是有问题的,因为它泄露了创建字体的上下文。解决这个简单的方法:不要有一个静态变量来保持对字体的引用。而是将上下文传递给辅助方法,以便为每个 Activity 创建一个新的 Typeface 实例。
  • 查看我的回答了解更多信息。

标签: java android public-method


【解决方案1】:

使用这个自定义字体类

public class TextView extends android.widget.TextView {
    Context mContext;
    String str;
    //fonts
    public static Typeface Font_name;

    public TextView(Context context) {
        super(context);
        mContext=context;


        initialiseFont(null);
    }



    public TextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext=context;
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TextView, 0, 0);
        try {
            str = ta.getString(R.styleable.TextView_font_family);

        } finally {
            ta.recycle();
        }
        initialiseFont(str);
    }

    public TextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext=context;
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TextView, 0, 0);
        try {
            str = ta.getString(R.styleable.TextView_font_family);

        } finally {
            ta.recycle();
        }
        initialiseFont(str);
    }

    public TextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mContext=context;
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TextView, 0, 0);
        try {
            str = ta.getString(R.styleable.TextView_font_family);

        } finally {
            ta.recycle();
        }
        initialiseFont(str);
    }
    private void initialiseFont(String font) {
        if(font==null || font.equals("")){

        }
        else {
            Font_name = Typeface.createFromAsset(mContext.getAssets(), font);
            setTypeface(Font_name);
        }

    }
}

在 arrs.xml 中添加这个标签来读取自定义属性 font-family

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

复制资产文件夹中的字体(使用相同的文件名),如果您在任何地方使用 TextView,请使用此标签

<Your_package_name_which_you_created_custom_font_class.TextView
        android:text="Hello World!"
        android:layout_width="wrap_content"
        app:font_family="OpenSans-Bold.ttf"
        android:layout_height="wrap_content" />

【讨论】:

    【解决方案2】:

    首先您必须创建一个名为 MasterActivity 的通用活动

    public class MasterActivity extends AppCompatActivity {
    
        protected Typeface titleFont;
    
        @Override
        public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
            super.onCreate(savedInstanceState, persistentState);
    
            // path for the fonts
            String fontTitle = "fonts/OpenSans-Bold.ttf";
    
            titleFont = Typeface.createFromAsset(getAssets(), fontTitle);
        }
    }
    

    然后让您的 MainActivity 从 MasterActivity 扩展,如下所示:

    public class MainActivity extends MasterActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // set the custom font
            page_title.setTypeface(titleFont);
        }
    }
    

    AboutActivity 也继承自 MasterActivity

    public class AboutActivity extends MasterActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_about);
    
            // set the custom font
            page_title.setTypeface(titleFont);
        }
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用静态工厂方法为每个 Activity 创建您的 Typeface 实例,如下所示:

      public class FontHelper {
      
          private static final String FONT_PATH = "fonts/OpenSans-Bold.ttf";
      
          public static Typeface getCustomTypeFace(Context context) {
              return Typeface.createFromAsset(context.getAssets(), FONT_PATH);
          }
      }
      

      你可以这样使用它:

      public class ExampleActivity extends AppCompatActivity {
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
      
              final Typeface typeface = FontHelper.getCustomTypeFace(this);
              ...
          }
      }
      

      【讨论】:

      • 谢谢,这正是我想要的。在您看来,这是更好还是在每个 Activity 中创建一个新的字体实例?
      • 这确实在每个 Activity 中创建了一个新字体,它只是在工厂中作为 FontHelper 类的一部分。这是您的用例的最佳解决方案。
      猜你喜欢
      • 2012-08-11
      • 2013-01-27
      • 2011-04-19
      • 2015-05-29
      • 2013-06-01
      • 2013-05-15
      相关资源
      最近更新 更多