我想自定义字体为我而我创建Android应用程序。 我可以分别更改从代码的每个对象的字体,但我有数百人。 所以, 有没有一种方法来从XML做到这一点? [设置自定义字体] 有没有一种方法,从代码做在一个地方,可以说,整个应用程序,而不是默认的,所有的自定义字体? 谢谢。 -Codevalley
本文地址 :CodeGo.net/162279/
-------------------------------------------------------------------------------------------------------------------------
1. 有没有办法从做到这一点 XML? 不,对不起。您只能通过XML指定内置字体。 有没有一种方法,从代码做的 一处,可以说,整个 应用程序和所有 自定义字体,而不是 默认1? 这并不是说我知道的。
2. 是的,这是可能的。 你必须创建一个扩展的文本视图自定义视图。 在
3. 虽然我upvoting Manish的答案 CodeGo.net,最快,最让我也看到了天真的解决方案,只是递归的视图层次遍历和更新又将所有字体。像这样:
4. 我并不需要改变布局XML或活动更“蛮力”的方式这样做。 测试在Android 2.x的(代码编写前一段时间)。纵观4.2.2 Android的字体类,我认为它会工作为Android 4.x的
5. 嘿,我还需要在我的应用程序2个不同字体,不同的widgeds! 这种方式: 在我的应用I类创建一个
6. 我觉得可以有一个更加便利的方式来做到这一点。下面的类将设置一个面子自定义类型的应用程序的(每类设置)所有。
7. 设置自定义字体到正规ProgressDialog / AlertDialog:
8. 我不知道,如果它改变了整个应用程序,但我已设法改变这种状况否则将无法做这个改变的组件:
9. 我喜欢pospi的建议。为什么不全力以赴视图的“标签”属性(可以在XML中指定-“android:标签')指定任何额外的样式,可以在XML中做。我喜欢JSON所以我一个JSON字符串来指定一个键/值集。这个类做的工作-只是调用
10. LayoutInflater默认不支持从XML指定字体的字体。不过,我已经看到它在做的xml提供了一个自定义的工厂,将解析从XML标记这些属性的LayoutInflater。 其基本结构会喜欢这个。
11. 我能做到这一点在一个集中的方式,下面是结果: 我刚刚从延长
12. 绝对有可能。 很多方法可以做到这一点。 最快的方法,用try创造条件- 试试你的某些字体样式条件下,捕获错误,并定义其他的字体样式。
13. 使用pospi的建议,并与“标签”属性像理查德那样工作,我创建了我的加载自定义字体,并根据他们的标签并将其应用到视图的自定义类。 而不是设置字体的属性android的所以基本上,:fontFamily中你的android:标签attritube并将其设置为已定义的enums之一。
本文标题 :在Android中使用自定义字体
本文地址 :CodeGo.net/162279/
本文地址 :CodeGo.net/162279/
-------------------------------------------------------------------------------------------------------------------------
1. 有没有办法从做到这一点 XML? 不,对不起。您只能通过XML指定内置字体。 有没有一种方法,从代码做的 一处,可以说,整个 应用程序和所有 自定义字体,而不是 默认1? 这并不是说我知道的。
2. 是的,这是可能的。 你必须创建一个扩展的文本视图自定义视图。 在
attrs.xml
在
values
文件夹:
<resources>
<declare-styleable name="MyTextView">
<attr name="first_name" format="string"/>
<attr name="last_name" format="string"/>
<attr name="ttf_name" format="string"/>
</declare-styleable>
</resources>
在
main.xml
:
<LinearLayout xmlns:android=" CodeGo.net
xmlns:lht=" CodeGo.net
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello"/>
<com.lht.ui.MyTextView
android:id="@+id/MyTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello friends"
lht:ttf_name="ITCBLKAD.TTF"
/>
</LinearLayout>
在
MyTextView.java
:
package com.lht.ui;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;
public class MyTextView extends TextView {
Context context;
String ttfName;
String TAG = getClass().getName();
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
for (int i = 0; i < attrs.getAttributeCount(); i++) {
Log.i(TAG, attrs.getAttributeName(i));
/*
* Read value of custom attributes
*/
this.ttfName = attrs.getAttributeValue(
" CodeGo.net "ttf_name");
Log.i(TAG, "firstText " + firstText);
// Log.i(TAG, "lastText "+ lastText);
init();
}
}
private void init() {
Typeface font = Typeface.createFromAsset(context.getAssets(), ttfName);
setTypeface(font);
}
@Override
public void setTypeface(Typeface tf) {
// TODO Auto-generated method stub
super.setTypeface(tf);
}
}
3. 虽然我upvoting Manish的答案 CodeGo.net,最快,最让我也看到了天真的解决方案,只是递归的视图层次遍历和更新又将所有字体。像这样:
public static void applyFonts(final View v, Typeface fontToSet)
{
try {
if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++) {
View child = vg.getChildAt(i);
applyFonts(child, fontToSet);
}
} else if (v instanceof TextView) {
((TextView)v).setTypeface(fontToSet);
}
} catch (Exception e) {
e.printStackTrace();
// ignore
}
}
您将需要两个后的布局和在你的Activity的调用这个函数对你的看法
onContentChanged()
方法。
4. 我并不需要改变布局XML或活动更“蛮力”的方式这样做。 测试在Android 2.x的(代码编写前一段时间)。纵观4.2.2 Android的字体类,我认为它会工作为Android 4.x的
private void setDefaultFont() {
try {
final Typeface bold = Typeface.createFromAsset(getAssets(), DEFAULT_BOLD_FONT_FILENAME);
final Typeface italic = Typeface.createFromAsset(getAssets(), DEFAULT_ITALIC_FONT_FILENAME);
final Typeface boldItalic = Typeface.createFromAsset(getAssets(), DEFAULT_BOLD_ITALIC_FONT_FILENAME);
final Typeface regular = Typeface.createFromAsset(getAssets(),DEFAULT_NORMAL_FONT_FILENAME);
Field DEFAULT = Typeface.class.getDeclaredField("DEFAULT");
DEFAULT.setAccessible(true);
DEFAULT.set(null, regular);
Field DEFAULT_BOLD = Typeface.class.getDeclaredField("DEFAULT_BOLD");
DEFAULT_BOLD.setAccessible(true);
DEFAULT_BOLD.set(null, bold);
Field sDefaults = Typeface.class.getDeclaredField("sDefaults");
sDefaults.setAccessible(true);
sDefaults.set(null, new Typeface[]{
regular, bold, italic, boldItalic
});
} catch (NoSuchFieldException e) {
logFontError(e);
} catch (IllegalAccessException e) {
logFontError(e);
} catch (Throwable e) {
//cannot crash app if there is a failure with overriding the default font!
logFontError(e);
}
5. 嘿,我还需要在我的应用程序2个不同字体,不同的widgeds! 这种方式: 在我的应用I类创建一个
public static Typeface getTypeface(Context context, String typeface) {
if (mFont == null) {
mFont = Typeface.createFromAsset(context.getAssets(), typeface);
}
return mFont;
}
弦乐字体表示的assets文件夹中的xyz.ttf。 (我创建了一个常量类) 现在,你这个无处不在你的应用程序:
mTextView = (TextView) findViewById(R.id.text_view);
mTextView.setTypeface(MyApplication.getTypeface(this, Constants.TYPEFACE_XY));
唯一的问题是,你需要这个,你想要的字体每一个部件! 但我认为这是最好的方式。
6. 我觉得可以有一个更加便利的方式来做到这一点。下面的类将设置一个面子自定义类型的应用程序的(每类设置)所有。
/**
* Base Activity of our app hierarchy.
* @author SNI
*/
public class BaseActivity extends Activity {
private static final String FONT_LOG_CAT_TAG = "FONT";
private static final boolean ENABLE_FONT_LOGGING = false;
private Typeface helloTypeface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
helloTypeface = Typeface.createFromAsset(getAssets(), "fonts/<your type face in assets/fonts folder>.ttf");
}
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
View view = super.onCreateView(name, context, attrs);
return setCustomTypeFaceIfNeeded(name, attrs, view);
}
@Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
View view = super.onCreateView(parent, name, context, attrs);
return setCustomTypeFaceIfNeeded(name, attrs, view);
}
protected View setCustomTypeFaceIfNeeded(String name, AttributeSet attrs, View view) {
View result = null;
if ("TextView".equals(name)) {
result = new TextView(this, attrs);
((TextView) result).setTypeface(helloTypeface);
}
if ("EditText".equals(name)) {
result = new EditText(this, attrs);
((EditText) result).setTypeface(helloTypeface);
}
if ("Button".equals(name)) {
result = new Button(this, attrs);
((Button) result).setTypeface(helloTypeface);
}
if (result == null) {
return view;
} else {
if (ENABLE_FONT_LOGGING) {
Log.v(FONT_LOG_CAT_TAG, "A type face was set on " + result.getId());
}
return result;
}
}
}
7. 设置自定义字体到正规ProgressDialog / AlertDialog:
font=Typeface.createFromAsset(getAssets(),"DroidSans.ttf");
ProgressDialog dialog = ProgressDialog.show(this, "titleText", "messageText", true);
((TextView)dialog.findViewById(Resources.getSystem().getIdentifier("message", "id", "android"))).setTypeface(font);
((TextView)dialog.findViewById(Resources.getSystem().getIdentifier("alertTitle", "id", "android"))).setTypeface(font);
8. 我不知道,如果它改变了整个应用程序,但我已设法改变这种状况否则将无法做这个改变的组件:
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/Lucida Sans Unicode.ttf");
Typeface.class.getField("DEFAULT").setAccessible(true);
Typeface.class.getField("DEFAULT_BOLD").setAccessible(true);
Typeface.class.getField("DEFAULT").set(null, tf);
Typeface.class.getField("DEFAULT_BOLD").set(null, tf);
9. 我喜欢pospi的建议。为什么不全力以赴视图的“标签”属性(可以在XML中指定-“android:标签')指定任何额外的样式,可以在XML中做。我喜欢JSON所以我一个JSON字符串来指定一个键/值集。这个类做的工作-只是调用
Style.setContentView(this, [resource id])
在您的活动。
public class Style {
/**
* Style a single view.
*/
public static void apply(View v) {
if (v.getTag() != null) {
try {
JSONObject json = new JSONObject((String)v.getTag());
if (json.has("typeface") && v instanceof TextView) {
((TextView)v).setTypeface(Typeface.createFromAsset(v.getContext().getAssets(),
json.getString("typeface")));
}
}
catch (JSONException e) {
// Some views have a tag without it being explicitly set!
}
}
}
/**
* Style the passed view hierarchy.
*/
public static View applyTree(View v) {
apply(v);
if (v instanceof ViewGroup) {
ViewGroup g = (ViewGroup)v;
for (int i = 0; i < g.getChildCount(); i++) {
applyTree(g.getChildAt(i));
}
}
return v;
}
/**
* Inflate, style, and set the content view for the passed activity.
*/
public static void setContentView(Activity activity, int resource) {
activity.setContentView(applyTree(activity.getLayoutInflater().inflate(resource, null)));
}
}
你会要处理的不仅仅是字体为JSON值得的。 “标签”属性的一个好处是,你可以在其上的,它会自动应用到所有的你的views基本样式设置。编辑:这样做会导致崩溃的通胀在Android 4.0.3中。您可以将样式并将其应用到个别文本的views。 有一件事你会看到在代码-视图都有一个标签无一被显式设置-奇怪的是字符串'Αποκοπή'-这是希腊“腰斩”,根据谷歌翻译!什么是地狱......?
10. LayoutInflater默认不支持从XML指定字体的字体。不过,我已经看到它在做的xml提供了一个自定义的工厂,将解析从XML标记这些属性的LayoutInflater。 其基本结构会喜欢这个。
public class TypefaceInflaterFactory implements LayoutInflater.Factory {
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
// CUSTOM CODE TO CREATE VIEW WITH TYPEFACE HERE
// RETURNING NULL HERE WILL TELL THE INFLATER TO USE THE
// DEFAULT MECHANISMS FOR INFLATING THE VIEW FROM THE XML
}
}
public class BaseActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater.from(this).setFactory(new TypefaceInflaterFactory());
}
}
本文提供了一个更深入的解释与笔者试图提供的字体的xml布局支持这种方式如何。对于作者的代码可以在这里找到。
11. 我能做到这一点在一个集中的方式,下面是结果: 我刚刚从延长
CustomFontActivity
。 下面是我做到了。
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater.Factory;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
public class CustomFontActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
getLayoutInflater().setFactory(new Factory() {
@Override
public View onCreateView(String name, Context context,
AttributeSet attrs) {
View v = tryInflate(name, context, attrs);
if (v instanceof TextView) {
setTypeFace((TextView) v);
}
return v;
}
});
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private View tryInflate(String name, Context context, AttributeSet attrs) {
LayoutInflater li = LayoutInflater.from(context);
View v = null;
try {
v = li.createView(name, null, attrs);
} catch (Exception e) {
try {
v = li.createView("android.widget." + name, null, attrs);
} catch (Exception e1) {
}
}
return v;
}
private void setTypeFace(TextView tv) {
tv.setTypeface(FontUtils.getFonts(this, "MTCORSVA.TTF"));
}
}
但如果我从支持包的活动如
FragmentActivity
我从延伸
CustomFontFragmentActivity
:
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
public class CustomFontFragmentActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// we can't setLayout Factory as its already set by FragmentActivity so we
// use this approach
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
View v = super.onCreateView(name, context, attrs);
if (v == null) {
v = tryInflate(name, context, attrs);
if (v instanceof TextView) {
setTypeFace((TextView) v);
}
}
return v;
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public View onCreateView(View parent, String name, Context context,
AttributeSet attrs) {
View v = super.onCreateView(parent, name, context, attrs);
if (v == null) {
v = tryInflate(name, context, attrs);
if (v instanceof TextView) {
setTypeFace((TextView) v);
}
}
return v;
}
private View tryInflate(String name, Context context, AttributeSet attrs) {
LayoutInflater li = LayoutInflater.from(context);
View v = null;
try {
v = li.createView(name, null, attrs);
} catch (Exception e) {
try {
v = li.createView("android.widget." + name, null, attrs);
} catch (Exception e1) {
}
}
return v;
}
private void setTypeFace(TextView tv) {
tv.setTypeface(FontUtils.getFonts(this, "MTCORSVA.TTF"));
}
}
我没有测试这个代码
Fragment
•本还,但希望它会奏效。 我的
FontUtils
很简单:
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.graphics.Typeface;
public class FontUtils {
private static Map<String, Typeface> TYPEFACE = new HashMap<String, Typeface>();
public static Typeface getFonts(Context context, String name) {
Typeface typeface = TYPEFACE.get(name);
if (typeface == null) {
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/"
+ name);
TYPEFACE.put(name, typeface);
}
return typeface;
}
}
12. 绝对有可能。 很多方法可以做到这一点。 最快的方法,用try创造条件- 试试你的某些字体样式条件下,捕获错误,并定义其他的字体样式。
13. 使用pospi的建议,并与“标签”属性像理查德那样工作,我创建了我的加载自定义字体,并根据他们的标签并将其应用到视图的自定义类。 而不是设置字体的属性android的所以基本上,:fontFamily中你的android:标签attritube并将其设置为已定义的enums之一。
public class Fonts {
private AssetManager mngr;
public Fonts(Context context) {
mngr = context.getAssets();
}
private enum AssetTypefaces {
RobotoLight,
RobotoThin,
RobotoCondensedBold,
RobotoCondensedLight,
RobotoCondensedRegular
}
private Typeface getTypeface(AssetTypefaces font) {
Typeface tf = null;
switch (font) {
case RobotoLight:
tf = Typeface.createFromAsset(mngr,"fonts/Roboto-Light.ttf");
break;
case RobotoThin:
tf = Typeface.createFromAsset(mngr,"fonts/Roboto-Thin.ttf");
break;
case RobotoCondensedBold:
tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Bold.ttf");
break;
case RobotoCondensedLight:
tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Light.ttf");
break;
case RobotoCondensedRegular:
tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Regular.ttf");
break;
default:
tf = Typeface.DEFAULT;
break;
}
return tf;
}
public void setupLayoutTypefaces(View v) {
try {
if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++) {
View child = vg.getChildAt(i);
setupLayoutTypefaces(child);
}
} else if (v instanceof TextView) {
if (v.getTag().toString().equals(AssetTypefaces.RobotoLight.toString())){
((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoLight));
}else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedRegular.toString())) {
((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedRegular));
}else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedBold.toString())) {
((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedBold));
}else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedLight.toString())) {
((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedLight));
}else if (v.getTag().toString().equals(AssetTypefaces.RobotoThin.toString())) {
((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoThin));
}
}
} catch (Exception e) {
e.printStackTrace();
// ignore
}
}
}
在你的活动或者你只需要调用
Fonts fonts = new Fonts(getActivity());
fonts.setupLayoutTypefaces(mainLayout);
本文标题 :在Android中使用自定义字体
本文地址 :CodeGo.net/162279/