在运行时添加字体资源
Add font ressource on runTime
我正在尝试向我的应用动态添加字体。我想根据我的服务器指示的字体在 运行 时间更改我的应用程序的每个 TextView 的字体。有没有办法下载字体(ttf 文件或其他)并在 运行 时间使用它?
提前致谢。
超级酷的问题,所以我要试一试并为您指明正确的方向,因为我绝对认为这是可能的。
首先,我想到了以下几点:
- 下载字体的东西
- 用来存放活动字体的东西
- 当字体不可用时处理它的一些方法(或者,更简单的是,在字体可用之前不显示任何内容)
- 使用活动字体的自定义 TextView
我将把第 1 留给你,因为我认为下载部分有点超出了如何实际使用字体的范围,而且有很多方法可以下载文件。
对于 #2,我们可以使用单例来保存对活动 TypeFace 的引用(这样我们就不会为每个想要使用它的视图重新创建它):
public class FontHolder {
private static FontHolder instance;
public static FontHolder getInstance(Context context){
if(instance == null)
instance = new FontHolder(context);
return instance;
}
private static final String PREF_TABLE = "font_prefs"
private static final String ACTIVE_FONT_PREF = "active_font_file";
private static final String DEFAULT_PREF_ASSET = "fonts/default_font.ttf";
private Context context;
private Typeface activeTypeFace;
protected FontHolder(Context context){
this.context = context.getApplicationContext();
String activeFilePath = getSavedActiveFont();
this.activeTypeFace = activeFilePath == null
? Typeface.createFromAssets(context.getResources().getAssets()
: Typeface.createFromFile(new File(activeFilePath));
}
private String getSavedActiveFont(){
return context.getSharedPreferences(PREF_TABLE, 0)
.getString(ACTIVE_FONT_PREF, null);
}
public void setActiveFont(File activeFontFile){
this.activeFont = Typeface.createFromFile(activeFontFile);
context.getSharedPreferences(PREF_TABLE, 0)
.edit()
.putString(ACTIVE_FONT_PREF, activeFontFile.getAbsolutePath())
.commit();
}
public Typeface getActiveFont(){
return activeFont;
}
}
如您所见,使用它我们可以轻松地更改实例中的活动字体,并在首选项中存储对该文件的引用以在会话之外持续存在。如果您想添加不同的变体(例如粗体、斜体等),您可以修改模板。
它还有一个资产文件的引用,默认字体为当前保存 none 时的字体。
现在我们需要一个自定义 TextView 来使用这个 TypeFace:
public class DynamicFontTextView extends TextView {
public DynamicFontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
updateActiveFont();
}
public DynamicFontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
updateActiveFont();
}
public DynamicFontTextView(Context context) {
super(context);
updateActiveFont();
}
@Override
public void setTypeface(Typeface tf, int style) {
// if(style == Typeface.BOLD) <-- Something for later
super.setTypeface(FontHolder.getInstance().getActiveFont());
}
public void updateActiveFont(){
super.setTypeface(FontHolder.getInstance().getActiveFont());
}
}
现在,在您的 XML 文件中,您可以将 DynamicFontTextView 与以下内容一起使用:
<com.package.DynamicFontTextView
....
/>
现在,回到第 3 部分。如果字体不可用,您将不得不下载它。下载时,您有 2 个选择:
A. Prevent them from getting to a screen where the custom font would ever be used.
B. Render with a default font, and then update the Views once the font is available
在这种情况下,让我们选择 A,因为它相对简单:只需创建一个初始页面,并且在字体下载完成之前不允许用户继续。
同样,初始页面有点超出了本文的范围,但希望这会为您指明正确的方向,帮助您完成任务。
我正在尝试向我的应用动态添加字体。我想根据我的服务器指示的字体在 运行 时间更改我的应用程序的每个 TextView 的字体。有没有办法下载字体(ttf 文件或其他)并在 运行 时间使用它?
提前致谢。
超级酷的问题,所以我要试一试并为您指明正确的方向,因为我绝对认为这是可能的。
首先,我想到了以下几点:
- 下载字体的东西
- 用来存放活动字体的东西
- 当字体不可用时处理它的一些方法(或者,更简单的是,在字体可用之前不显示任何内容)
- 使用活动字体的自定义 TextView
我将把第 1 留给你,因为我认为下载部分有点超出了如何实际使用字体的范围,而且有很多方法可以下载文件。
对于 #2,我们可以使用单例来保存对活动 TypeFace 的引用(这样我们就不会为每个想要使用它的视图重新创建它):
public class FontHolder {
private static FontHolder instance;
public static FontHolder getInstance(Context context){
if(instance == null)
instance = new FontHolder(context);
return instance;
}
private static final String PREF_TABLE = "font_prefs"
private static final String ACTIVE_FONT_PREF = "active_font_file";
private static final String DEFAULT_PREF_ASSET = "fonts/default_font.ttf";
private Context context;
private Typeface activeTypeFace;
protected FontHolder(Context context){
this.context = context.getApplicationContext();
String activeFilePath = getSavedActiveFont();
this.activeTypeFace = activeFilePath == null
? Typeface.createFromAssets(context.getResources().getAssets()
: Typeface.createFromFile(new File(activeFilePath));
}
private String getSavedActiveFont(){
return context.getSharedPreferences(PREF_TABLE, 0)
.getString(ACTIVE_FONT_PREF, null);
}
public void setActiveFont(File activeFontFile){
this.activeFont = Typeface.createFromFile(activeFontFile);
context.getSharedPreferences(PREF_TABLE, 0)
.edit()
.putString(ACTIVE_FONT_PREF, activeFontFile.getAbsolutePath())
.commit();
}
public Typeface getActiveFont(){
return activeFont;
}
}
如您所见,使用它我们可以轻松地更改实例中的活动字体,并在首选项中存储对该文件的引用以在会话之外持续存在。如果您想添加不同的变体(例如粗体、斜体等),您可以修改模板。
它还有一个资产文件的引用,默认字体为当前保存 none 时的字体。
现在我们需要一个自定义 TextView 来使用这个 TypeFace:
public class DynamicFontTextView extends TextView {
public DynamicFontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
updateActiveFont();
}
public DynamicFontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
updateActiveFont();
}
public DynamicFontTextView(Context context) {
super(context);
updateActiveFont();
}
@Override
public void setTypeface(Typeface tf, int style) {
// if(style == Typeface.BOLD) <-- Something for later
super.setTypeface(FontHolder.getInstance().getActiveFont());
}
public void updateActiveFont(){
super.setTypeface(FontHolder.getInstance().getActiveFont());
}
}
现在,在您的 XML 文件中,您可以将 DynamicFontTextView 与以下内容一起使用:
<com.package.DynamicFontTextView
....
/>
现在,回到第 3 部分。如果字体不可用,您将不得不下载它。下载时,您有 2 个选择:
A. Prevent them from getting to a screen where the custom font would ever be used.
B. Render with a default font, and then update the Views once the font is available
在这种情况下,让我们选择 A,因为它相对简单:只需创建一个初始页面,并且在字体下载完成之前不允许用户继续。
同样,初始页面有点超出了本文的范围,但希望这会为您指明正确的方向,帮助您完成任务。