アプリケーションのすべてのコントロールにカスタムフォントを設定することは可能ですか?そして、必ずしもランタイムではありませんか? (つまり、可能であればxmlから、またはJava file)のアプリケーション全体に対して1回のみ)
このコードから1つのコントロールのフォントを設定できます。
public static void setFont(TextView textView) {
Typeface tf = Typeface.createFromAsset(textView.getContext()
.getAssets(), "fonts/BPreplay.otf");
textView.setTypeface(tf);
}
このコードの問題は、すべてのコントロールに対して呼び出す必要があることです。そして、私はこれまたは同様のメソッドを1回呼び出すか、可能であればxmlでプロパティを設定します。出来ますか?
[〜#〜] edit [〜#〜]:それでしばらく経ちましたが、最良と思われる方法を追加したいと思いますこれを行うには、XMLを使用します。
そのため、最初に、カスタマイズするビューをオーバーライドする新しいクラスを作成する必要があります。 (たとえば、カスタム書体のボタンが必要ですか?Button
を拡張します)。例を作りましょう:
public class CustomButton extends Button {
private final static int ROBOTO = 0;
private final static int ROBOTO_CONDENSED = 1;
public CustomButton(Context context) {
super(context);
}
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs); //I'll explain this method later
}
public CustomButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
}
まだない場合は、res/values/attrs.xml
の下にXMLドキュメントを追加し、次を追加します。
<resources>
<!-- Define the values for the attribute -->
<attr name="typeface" format="enum">
<enum name="roboto" value="0"/>
<enum name="robotoCondensed" value="1"/>
</attr>
<!-- Tell Android that the class "CustomButton" can be styled,
and which attributes it supports -->
<declare-styleable name="CustomButton">
<attr name="typeface"/>
</declare-styleable>
</resources>
さて、それで邪魔にならないように、前のparseAttributes()
メソッドに戻りましょう。
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.CustomButton);
//The value 0 is a default, but shouldn't ever be used since the attr is an enum
int typeface = values.getInt(R.styleable.CustomButton_typeface, 0);
switch(typeface) {
case ROBOTO: default:
//You can instantiate your typeface anywhere, I would suggest as a
//singleton somewhere to avoid unnecessary copies
setTypeface(roboto);
break;
case ROBOTO_CONDENSED:
setTypeface(robotoCondensed);
break;
}
values.recycle();
}
これで準備は完了です。さまざまな属性を追加できます(typefaceStyleに別の属性(太字、斜体など)を追加できます)が、使用方法を見てみましょう。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:custom="http://schemas.Android.com/apk/res/com.yourpackage.name"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical" >
<com.yourpackage.name.CustomButton
Android:id="@+id/button"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Click Me!"
custom:typeface="roboto" />
</LinearLayout>
xmlns:custom
行は実際には何でもかまいませんが、規則は上記のとおりです。重要なのは、それが一意であり、パッケージ名が使用される理由です。これで、属性にcustom:
プレフィックスを使用し、Android属性にAndroid:
プレフィックスを使用します。
最後に、スタイル(res/values/styles.xml
)でこれを使用する場合は、notを追加する必要がありますxmlns:custom
行。プレフィックスなしで属性の名前を参照するだけです:
<style name="MyStyle>
<item name="typeface">roboto</item>
</style>
(PREVIOUS ANSWER)
これは役立つはずです。基本的に、XMLでこれを行う方法はなく、私が知る限り、コードでそれを行う簡単な方法はありません。書体を1回作成し、それぞれに対してsetTypeface()を実行するsetLayoutFont()メソッドを常に使用できます。レイアウトに新しいアイテムを追加するたびに更新する必要があります。以下のようなもの:
public void setLayoutFont() {
Typeface tf = Typeface.createFromAsset(
getBaseContext().getAssets(), "fonts/BPreplay.otf");
TextView tv1 = (TextView)findViewById(R.id.tv1);
tv1.setTypeface(tf);
TextView tv2 = (TextView)findViewById(R.id.tv2);
tv2.setTypeface(tf);
TextView tv3 = (TextView)findViewById(R.id.tv3);
tv3.setTypeface(tf);
}
[〜#〜] edit [〜#〜]:だから私はこのようなものを自分で実装することに取り掛かりました。次のような関数を作成します。
public static void setLayoutFont(Typeface tf, TextView...params) {
for (TextView tv : params) {
tv.setTypeface(tf);
}
}
次に、onCreate()からこのメソッドを使用して、更新するすべてのTextViewを渡します。
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
//find views by id...
setLayoutFont(tf, tv1, tv2, tv3, tv4, tv5);
EDIT 9/5/12:
だから、これはまだビューと投票を得ているので、私ははるかに優れた、より完全なメソッドを追加したいと思います
Typeface mFont = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
ViewGroup root = (ViewGroup)findViewById(R.id.myrootlayout);
setFont(root, mFont);
/*
* Sets the font on all TextViews in the ViewGroup. Searches
* recursively for all inner ViewGroups as well. Just add a
* check for any other views you want to set as well (EditText,
* etc.)
*/
public void setFont(ViewGroup group, Typeface font) {
int count = group.getChildCount();
View v;
for(int i = 0; i < count; i++) {
v = group.getChildAt(i);
if(v instanceof TextView || v instanceof Button /*etc.*/)
((TextView)v).setTypeface(font);
else if(v instanceof ViewGroup)
setFont((ViewGroup)v, font);
}
}
レイアウトのルートを渡すと、そのレイアウト内でTextView
またはButton
ビュー(またはifステートメントに追加する他のビュー)を再帰的にチェックし、ユーザーなしでフォントを設定します。 IDで指定する必要があります。もちろん、これはフォントをevery viewに設定することを前提としています。
XMLを介してこれを行うには、かなり簡単な方法があります。 TextViewを拡張する独自のウィジェットを作成するだけです。
最初に、res/values/attrs.xmlに次の内容のファイルを作成します。
_<resources>
<declare-styleable name="TypefacedTextView">
<attr name="typeface" format="string" />
</declare-styleable>
</resources>
_
その後、カスタムウィジェットを作成します。
_package your.package.widget;
public class TypefacedTextView extends TextView {
public TypefacedTextView(Context context, AttributeSet attrs) {
super(context, attrs);
//Typeface.createFromAsset doesn't work in the layout editor. Skipping...
if (isInEditMode()) {
return;
}
TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.TypefacedTextView);
String fontName = styledAttrs.getString(R.styleable.TypefacedTextView_typeface);
styledAttrs.recycle();
if (fontName != null) {
Typeface typeface = Typeface.createFromAsset(context.getAssets(), fontName);
setTypeface(typeface);
}
}
}
_
ご覧のとおり、上記のコードは、assets /フォルダー内のフォントを読み取ります。この例では、アセットフォルダーに「custom.ttf」というファイルがあると想定しています。最後に、XMLでウィジェットを使用します。
_<your.package.widget.TypefacedTextView
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:your_namespace="http://schemas.Android.com/apk/res/your.package"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:text="Custom fonts in XML are easy"
Android:textColor="#FFF"
Android:textSize="14dip"
your_namespace:typeface="custom.ttf" />
_
注:Eclipseのレイアウトエディターでカスタムフォントを表示することはできません。これがisInEditMode()
チェックを入れた理由です。しかし、アプリを実行すると、カスタムフォントは魅力のように機能します。
それが役に立てば幸い!
Roboto書体を使用したTextViewの例:
attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RobotoTextView">
<attr name="typeface"/>
</declare-styleable>
<attr name="typeface" format="enum">
<enum name="roboto_thin" value="0"/>
<enum name="roboto_thin_italic" value="1"/>
<enum name="roboto_light" value="2"/>
<enum name="roboto_light_italic" value="3"/>
<enum name="roboto_regular" value="4"/>
<enum name="roboto_italic" value="5"/>
<enum name="roboto_medium" value="6"/>
<enum name="roboto_medium_italic" value="7"/>
<enum name="roboto_bold" value="8"/>
<enum name="roboto_bold_italic" value="9"/>
<enum name="roboto_black" value="10"/>
<enum name="roboto_black_italic" value="11"/>
<enum name="roboto_condensed" value="12"/>
<enum name="roboto_condensed_italic" value="13"/>
<enum name="roboto_condensed_bold" value="14"/>
<enum name="roboto_condensed_bold_italic" value="15"/>
</attr>
</resources>
RobotoTextView.Java:
public class RobotoTextView extends TextView {
/*
* Permissible values for the "typeface" attribute.
*/
private final static int ROBOTO_THIN = 0;
private final static int ROBOTO_THIN_ITALIC = 1;
private final static int ROBOTO_LIGHT = 2;
private final static int ROBOTO_LIGHT_ITALIC = 3;
private final static int ROBOTO_REGULAR = 4;
private final static int ROBOTO_ITALIC = 5;
private final static int ROBOTO_MEDIUM = 6;
private final static int ROBOTO_MEDIUM_ITALIC = 7;
private final static int ROBOTO_BOLD = 8;
private final static int ROBOTO_BOLD_ITALIC = 9;
private final static int ROBOTO_BLACK = 10;
private final static int ROBOTO_BLACK_ITALIC = 11;
private final static int ROBOTO_CONDENSED = 12;
private final static int ROBOTO_CONDENSED_ITALIC = 13;
private final static int ROBOTO_CONDENSED_BOLD = 14;
private final static int ROBOTO_CONDENSED_BOLD_ITALIC = 15;
/**
* List of created typefaces for later reused.
*/
private final static SparseArray<Typeface> mTypefaces = new SparseArray<Typeface>(16);
/**
* Simple constructor to use when creating a view from code.
*
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
*/
public RobotoTextView(Context context) {
super(context);
}
/**
* Constructor that is called when inflating a view from XML. This is called
* when a view is being constructed from an XML file, supplying attributes
* that were specified in the XML file. This version uses a default style of
* 0, so the only attribute values applied are those in the Context's Theme
* and the given AttributeSet.
* <p/>
* <p/>
* The method onFinishInflate() will be called after all children have been
* added.
*
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* @param attrs The attributes of the XML tag that is inflating the view.
* @see #RobotoTextView(Context, AttributeSet, int)
*/
public RobotoTextView(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs);
}
/**
* Perform inflation from XML and apply a class-specific base style. This
* constructor of View allows subclasses to use their own base style when
* they are inflating.
*
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* @param attrs The attributes of the XML tag that is inflating the view.
* @param defStyle The default style to apply to this view. If 0, no style
* will be applied (beyond what is included in the theme). This may
* either be an attribute resource, whose value will be retrieved
* from the current theme, or an explicit style resource.
* @see #RobotoTextView(Context, AttributeSet)
*/
public RobotoTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
/**
* Parse the attributes.
*
* @param context The Context the view is running in, through which it can access the current theme, resources, etc.
* @param attrs The attributes of the XML tag that is inflating the view.
*/
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.RobotoTextView);
int typefaceValue = values.getInt(R.styleable.RobotoTextView_typeface, 0);
values.recycle();
setTypeface(obtaintTypeface(context, typefaceValue));
}
/**
* Obtain typeface.
*
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* @param typefaceValue values for the "typeface" attribute
* @return Roboto {@link Typeface}
* @throws IllegalArgumentException if unknown `typeface` attribute value.
*/
private Typeface obtaintTypeface(Context context, int typefaceValue) throws IllegalArgumentException {
Typeface typeface = mTypefaces.get(typefaceValue);
if (typeface == null) {
typeface = createTypeface(context, typefaceValue);
mTypefaces.put(typefaceValue, typeface);
}
return typeface;
}
/**
* Create typeface from assets.
*
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* @param typefaceValue values for the "typeface" attribute
* @return Roboto {@link Typeface}
* @throws IllegalArgumentException if unknown `typeface` attribute value.
*/
private Typeface createTypeface(Context context, int typefaceValue) throws IllegalArgumentException {
Typeface typeface;
switch (typefaceValue) {
case ROBOTO_THIN:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Thin.ttf");
break;
case ROBOTO_THIN_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-ThinItalic.ttf");
break;
case ROBOTO_LIGHT:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Light.ttf");
break;
case ROBOTO_LIGHT_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-LightItalic.ttf");
break;
case ROBOTO_REGULAR:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Regular.ttf");
break;
case ROBOTO_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Italic.ttf");
break;
case ROBOTO_MEDIUM:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Medium.ttf");
break;
case ROBOTO_MEDIUM_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-MediumItalic.ttf");
break;
case ROBOTO_BOLD:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Bold.ttf");
break;
case ROBOTO_BOLD_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldItalic.ttf");
break;
case ROBOTO_BLACK:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Black.ttf");
break;
case ROBOTO_BLACK_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BlackItalic.ttf");
break;
case ROBOTO_CONDENSED:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Condensed.ttf");
break;
case ROBOTO_CONDENSED_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-CondensedItalic.ttf");
break;
case ROBOTO_CONDENSED_BOLD:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldCondensed.ttf");
break;
case ROBOTO_CONDENSED_BOLD_ITALIC:
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldCondensedItalic.ttf");
break;
default:
throw new IllegalArgumentException("Unknown `typeface` attribute value " + typefaceValue);
}
return typeface;
}
}
使用例:
<your.package.widget.RobotoTextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:typeface="roboto_thin"
Android:textSize="22sp"
Android:text="Roboto Thin"/>
リソース: Roboto&Notoフォント
遅すぎますが、他の人の助けになります
iはtypeFaceと呼ばれる属性を持つCustomTextViewを作成しました。これは、キャッシュなしで書体をロードする際のメモリリーク問題を処理します。
まず、アセットからフォントを一度だけロードするFonts
クラス
import Android.content.Context;
import Android.graphics.Typeface;
import Java.util.Hashtable;
/**
* Created by tonyhaddad on 7/19/15.
*/
public class Fonts {
private Context context;
public Fonts(Context context) {
this.context = context;
}
private static Hashtable<String, Typeface> sTypeFaces = new Hashtable<String, Typeface>(
4);
public static Typeface getTypeFace(Context context, String fileName) {
Typeface tempTypeface = sTypeFaces.get(fileName);
if (tempTypeface == null) {
String fontPath=null;
if(fileName=="metabold")
fontPath ="fonts/Meta-Bold.ttf";
else if(fileName=="metanormal")
fontPath="fonts/Meta-Normal.ttf";
else if(fileName=="gsligh")
fontPath="fonts/gesslight.ttf";
else if(fileName=="bold")
fontPath="fonts/Lato-Bold.ttf";
else if(fileName=="rcr")
fontPath="fonts/RobotoCondensed-Regular.ttf";
else if(fileName=="mpr")
fontPath="fonts/MyriadPro-Regular.otf";
else if(fileName=="rr")
fontPath="fonts/Roboto-Regular.ttf";
tempTypeface = Typeface.createFromAsset(context.getAssets(), fontPath);
sTypeFaces.put(fileName, tempTypeface);
}
return tempTypeface;
}
}
次に、attrs.xmlにカスタム属性を追加する必要があります
<declare-styleable name="CustomFontTextView">
<attr name="typeFace" format="string" />
</declare-styleable>
その後、カスタムクラス
package package_name;
/**
* Created by tonyhaddad on 8/26/15.
*/
import Android.content.Context;
import Android.content.res.TypedArray;
import Android.graphics.Typeface;
import Android.util.AttributeSet;
import Android.widget.TextView;
import package_name.R;
public class CustomFontTextView extends TextView {
String typeFace;
public CustomFontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) {
return;
}
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.CustomFontTextView,
0, 0);
try {
typeFace = a.getString(0);
} finally {
a.recycle();
}
if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
{
Typeface tf = Fonts.getTypeFace(context, typeFace);
setTypeface(tf);
}
init();
}
public CustomFontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
if (isInEditMode()) {
return;
}
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.CustomFontTextView,
0, 0);
try {
typeFace = a.getString(0);
} finally {
a.recycle();
}
if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
{
Typeface tf = Fonts.getTypeFace(context, typeFace);
setTypeface(tf);
}
init();
}
public CustomFontTextView(Context context) {
super(context);
if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
{
Typeface tf = Fonts.getTypeFace(context, typeFace);
setTypeface(tf);
}
init();
}
private void init() {
}
public String getTypeFace() {
return typeFace;
}
public void setTypeFace(String typeFace) {
this.typeFace = typeFace;
invalidate();
requestLayout();
}
}
最後にテキストビューを追加します
<package_name.CustomFontTextView
xmlns:custom="http://schemas.Android.com/apk/res-auto/package_name"
Android:id="@+id/txt"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_centerVertical="true"
Android:layout_marginLeft="41dp"
Android:gravity="center_vertical"
Android:text="text"
Android:textColor="#000"
Android:textSize="23sp"
custom:typeFace="metanormal"/>
また、setTypeFaceメソッドを使用して、フォントをプログラムで変更できます。
このビューで複数の名前空間を使用する場合は、カスタムネームスペースを親レイアウトに移動することもできます
ハッピーコーディング:)
より一般的なプログラムによるソリューションを探している場合は、ビュー全体のアクティビティを設定するために使用できる静的クラスを作成しました(アクティビティUI)。私はMono(C#)で作業していますが、Javaを使用して簡単に実装できることに注意してください。
このクラスに、カスタマイズしたいレイアウトまたは特定のビューを渡すことができます。超効率的にしたい場合は、Singletonパターンを使用して実装できます。
public static class AndroidTypefaceUtility
{
static AndroidTypefaceUtility()
{
}
//Refer to the code block beneath this one, to see how to create a typeface.
public static void SetTypefaceOfView(View view, Typeface customTypeface)
{
if (customTypeface != null && view != null)
{
try
{
if (view is TextView)
(view as TextView).Typeface = customTypeface;
else if (view is Button)
(view as Button).Typeface = customTypeface;
else if (view is EditText)
(view as EditText).Typeface = customTypeface;
else if (view is ViewGroup)
SetTypefaceOfViewGroup((view as ViewGroup), customTypeface);
else
Console.Error.WriteLine("AndroidTypefaceUtility: {0} is type of {1} and does not have a typeface property", view.Id, typeof(View));
}
catch (Exception ex)
{
Console.Error.WriteLine("AndroidTypefaceUtility threw:\n{0}\n{1}", ex.GetType(), ex.StackTrace);
throw ex;
}
}
else
{
Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / view parameter should not be null");
}
}
public static void SetTypefaceOfViewGroup(ViewGroup layout, Typeface customTypeface)
{
if (customTypeface != null && layout != null)
{
for (int i = 0; i < layout.ChildCount; i++)
{
SetTypefaceOfView(layout.GetChildAt(i), customTypeface);
}
}
else
{
Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / layout parameter should not be null");
}
}
}
アクティビティでは、Typefaceオブジェクトを作成する必要があります。 Resources/Assets /ディレクトリにある.ttfファイルを使用してOnCreate()で作成します。ファイルがプロパティでAndroid Assetとしてマークされていることを確認してください。
protected override void OnCreate(Bundle bundle)
{
...
LinearLayout rootLayout = (LinearLayout)FindViewById<LinearLayout>(Resource.Id.signInView_LinearLayout);
Typeface allerTypeface = Typeface.CreateFromAsset(base.Assets,"Aller_Rg.ttf");
AndroidTypefaceUtility.SetTypefaceOfViewGroup(rootLayout, allerTypeface);
}
OnCreate()で呼び出され、最も外側のViewGroupに渡された以下のメソッドは、動的に作成されるテキスト(動的リスト、アラートなど)を除くすべてに対して機能します。最も外側のViewGroupを取得する簡単な方法は、ビューのいずれかでgetRootViewを使用することです。
public void onCreate(Bundle savedInstanceState){
//onCreate code...
EditText text = (EditText) findViewById(R.id.editText1);
setTypeFaceForViewGroup((ViewGroup) text.getRootView());
}
private void setTypeFaceForViewGroup(ViewGroup vg){
for (int i = 0; i < vg.getChildCount(); i++) {
if (vg.getChildAt(i) instanceof ViewGroup)
setTypeFaceForViewGroup((ViewGroup) vg.getChildAt(i));
else if (vg.getChildAt(i) instanceof TextView)
((TextView) vg.getChildAt(i)).setTypeface(Typeface.createFromAsset(getAssets(), "fonts/Your_Font.ttf"));
}
}
これは動的コンテンツでも同様に機能するはずです。作成した直後に、作成したものを渡して呼び出すだけです(ただし、これはテストしていません)。
メモリを節約するために、おそらくここにあるようにループが実行されるたびに新しいものを作成するのではなく、書体を静的変数にしたいと思うでしょう。
leocadiotine
の優れたソリューションにメモを追加したいと思います。それは完璧ですが、このカスタムTextViewを何度も使用すると、textviewが作成されるたびにアセットにアクセスする必要があるため、アプリケーションの速度が低下します。 Adapters
でView Holder pattern
のようなものを使用することをお勧めします。
public class Fonts {
private static final Map<String, Typeface> typefaces = new HashMap<String, Typeface>();
public static Typeface getTypeface(Context ctx, String fontName) {
Typeface typeface = typefaces.get(fontName);
if (typeface == null) {
typeface = Typeface.createFromAsset(ctx.getAssets(), fontName);
typefaces.put(fontName, typeface);
}
return typeface;
}
}
このようにして、アプリケーションはアセットごとに1回だけアセットにアクセスし、さらに必要に応じてそれらをメモリに保持します。
残念なことに、Androidは、アプリ全体のフォントを変更するための迅速で簡単できれいな方法を提供していません。しかし最近、この問題を調査し、いくつかのツールを作成しましたこれにより、コーディングなしでフォントを変更することができます(xml、スタイル、テキストの外観を使用してすべてを行うことができます)。これらは、他の回答で見られるような同様のソリューションに基づいていますが、はるかに柔軟性があります。 このブログ でそれに関するすべてを読むことができ、githubプロジェクト here を見ることができます。
これらのツールを適用する方法の例を次に示します。すべてのフォントファイルを_assets/fonts/
_に入れます。次に、これらのフォントをxmlファイル(たとえば_res/xml/fonts.xml
_)で宣言し、TypefaceManager.initialize(this, R.xml.fonts);
を使用してアプリの早い段階でこのファイルを読み込みます(たとえば、アプリケーションクラスのonCreateで)。 xmlファイルは次のようになります。
_<?xml version="1.0" encoding="utf-8"?>
<familyset>
<!-- Some Font. Can be referenced with 'someFont' or 'aspergit' -->
<family>
<nameset>
<name>aspergit</name>
<name>someFont</name>
</nameset>
<fileset>
<file>Aspergit.ttf</file>
<file>Aspergit Bold.ttf</file>
<file>Aspergit Italic.ttf</file>
<file>Aspergit Bold Italic.ttf</file>
</fileset>
</family>
<!-- Another Font. Can be referenced with 'anotherFont' or 'bodoni' -->
<family>
<nameset>
<name>bodoni</name>
<name>anotherFont</name>
</nameset>
<fileset>
<file>BodoniFLF-Roman.ttf</file>
<file>BodoniFLF-Bold.ttf</file>
</fileset>
</family>
</familyset>
_
これで、xmlレイアウトでカスタムUI要素_com.innovattic.font.FontTextView
_を使用して、これらのフォントをスタイルまたはxml(上記のツールを使用する場合)で使用できます。 _res/values/styles.xml
_を編集するだけで、アプリ全体のすべてのテキストにフォントを適用する方法を以下に示します。
_<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:Android="http://schemas.Android.com/apk/res/Android" xmlns:tools="http://schemas.Android.com/tools">
<!-- Application theme -->
<!-- Use a different parent if you don't want Holo Light -->
<style name="AppTheme" parent="Android:Theme.Holo.Light.DarkActionBar">
<item name="Android:textViewStyle">@style/MyTextViewStyle</item>
</style>
<!-- Style to use for ALL text views (including FontTextView) -->
<!-- Use a different parent if you don't want Holo Light -->
<style name="MyTextViewStyle" parent="@Android:style/Widget.Holo.Light.TextView">
<item name="Android:textAppearance">@style/MyTextAppearance</item>
</style>
<!-- Text appearance to use for ALL text views (including FontTextView) -->
<!-- Use a different parent if you don't want Holo Light -->
<style name="MyTextAppearance" parent="@Android:style/TextAppearance.Holo">
<!-- Alternatively, reference this font with the name "aspergit" -->
<!-- Note that only our own TextView's will use the font attribute -->
<item name="flFont">someFont</item>
<item name="Android:textStyle">bold|italic</item>
</style>
<!-- Alternative style, maybe for some other widget -->
<style name="StylishFont">
<item name="flFont">anotherFont</item>
<item name="Android:textStyle">normal</item>
</style>
</resources>
_
付属の_res/layout/layout.xml
_を使用:
_<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context=".MainActivity" >
<!-- This text view is styled with the app theme -->
<com.innovattic.font.FontTextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="This uses my font in bold italic style" />
<!-- This text view is styled here and overrides the app theme -->
<com.innovattic.font.FontTextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:flFont="anotherFont"
Android:textStyle="normal"
Android:text="This uses another font in normal style" />
<!-- This text view is styled with a style and overrides the app theme -->
<com.innovattic.font.FontTextView
style="@style/StylishFont"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="This also uses another font in normal style" />
</LinearLayout>
_
Androidマニフェストでテーマを適用することを忘れないでください。
Android 8.0(APIレベル26)には、XMLのフォントという新機能が導入されています。fontfamilyファイルを作成して、styles.xmlに設定できます。
フォントをリソースとして追加するには、Android Studioで次の手順を実行します。
1. resフォルダーを右クリックして、新規> Android resource directory。New Resource Directoryウィンドウが表示されます。
2. [リソースタイプ]リストでフォントを選択し、[OK]をクリックします。注:リソースディレクトリの名前はフォントである必要があります。
3.フォントフォルダーにフォントファイルを追加します。
フォントファミリを作成するには、次の手順を実行します。
1.フォントフォルダーを右クリックし、[新規]> [フォントリソースファイル]に移動します。 [新しいリソースファイル]ウィンドウが表示されます。
2.ファイル名を入力し、[OK]をクリックします。新しいフォントリソースXMLがエディターで開きます。
3.要素内の各フォントファイル、スタイル、および重量属性を囲みます。次のXMLは、フォント関連の属性をフォントリソースXMLに追加する方法を示しています。
<?xml version="1.0" encoding="utf-8"?> <font-family xmlns:Android="http://schemas.Android.com/apk/res/Android"> <font Android:fontStyle="normal" Android:fontWeight="400" Android:font="@font/lobster_regular" /> <font Android:fontStyle="italic" Android:fontWeight="400" Android:font="@font/lobster_italic" /> </font-family>
フォントをスタイルに追加する
Styles.xmlを開き、fontFamily属性をアクセスするフォントファイルに設定します。
<style name="customfontstyle" parent="@Android:style/TextAppearance.Small"> <item name="Android:fontFamily">@font/lobster</item> </style>
ソース: XMLのフォント
このリンク、リンクでステップバイステップの情報を見つけました: https://github.com/jaydipumaretiya/CustomTypeface/
Androidで書体を正しく使用するには多くの方法があります。メインの下にあるアセットフォルダーに書体ファイルを直接配置する必要があり、実行時に使用できます。
他の最も簡単な方法は、デフォルトライブラリを使用してxmlファイルに書体を設定することです。このカスタム書体ライブラリは、書体をTextView、EditText、Button、CheckBox、RadioButton、AutoCompleteTextView、およびAndroidの他のウェッジに設定することを好みます。
アプリ全体が変更されるかどうかはわかりませんが、これを行うことで他の方法では変更できないコンポーネントを変更することができました。
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);