AndroidでXMLファイルを使用してGUIレイアウトを定義しようとしています。私が知る限り、ウィジェットがXMLファイルでカスタムフォント(たとえばassets/font /に配置したもの)を使用するように指定する方法はなく、システムにインストールされたフォントのみを使用できます。
Javaコードでは、一意のIDを使用して各ウィジェットのフォントを手動で変更できることを知っています。あるいは、Java内のすべてのウィジェットを繰り返してこの変更を行うこともできますが、これはおそらく非常に遅いでしょう。
他にどんなオプションがありますか?カスタムの外観を持つウィジェットを作成するより良い方法はありますか?特に、追加する新しいウィジェットごとにフォントを手動で変更する必要はありません。
TextViewを拡張して、私が学んだようにカスタムフォントを設定できます here 。
TextViewPlus.Java:
package com.example;
import Android.content.Context;
import Android.content.res.TypedArray;
import Android.graphics.Typeface;
import Android.util.AttributeSet;
import Android.util.Log;
import Android.widget.TextView;
public class TextViewPlus extends TextView {
private static final String TAG = "TextView";
public TextViewPlus(Context context) {
super(context);
}
public TextViewPlus(Context context, AttributeSet attrs) {
super(context, attrs);
setCustomFont(context, attrs);
}
public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setCustomFont(context, attrs);
}
private void setCustomFont(Context ctx, AttributeSet attrs) {
TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus);
String customFont = a.getString(R.styleable.TextViewPlus_customFont);
setCustomFont(ctx, customFont);
a.recycle();
}
public boolean setCustomFont(Context ctx, String asset) {
Typeface tf = null;
try {
tf = Typeface.createFromAsset(ctx.getAssets(), asset);
} catch (Exception e) {
Log.e(TAG, "Could not get typeface: "+e.getMessage());
return false;
}
setTypeface(tf);
return true;
}
}
attrs.xml:(res/values)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TextViewPlus">
<attr name="customFont" format="string"/>
</declare-styleable>
</resources>
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:foo="http://schemas.Android.com/apk/res/com.example"
Android:orientation="vertical" Android:layout_width="fill_parent"
Android:layout_height="fill_parent">
<com.example.TextViewPlus
Android:id="@+id/textViewPlus1"
Android:layout_height="match_parent"
Android:layout_width="match_parent"
Android:text="@string/showingOffTheNewTypeface"
foo:customFont="saxmono.ttf">
</com.example.TextViewPlus>
</LinearLayout>
assetsフォルダーに「saxmono.ttf」を配置します。
このメソッドにはメモリに関する深刻な問題があります。 chedabobのコメント を参照してください。
私はパーティーに3年遅れています:(しかし、これはこの投稿につまずくかもしれない人にとって有用かもしれません。
タイプフェイスをキャッシュし、XMLから直接カスタムタイプフェイスを指定できるようにするライブラリを作成しました。ライブラリを見つけることができます こちら 。
XMLレイアウトを使用すると、次のようになります。
<com.mobsandgeeks.ui.TypefaceTextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="@string/hello_world"
geekui:customTypeface="fonts/custom_font.ttf" />
これは少し遅れる可能性がありますが、メモリリークを避けるために、カスタム書体を返すシングルトンクラスを作成する必要があります。
TypeFaceクラス:
public class OpenSans {
private static OpenSans instance;
private static Typeface typeface;
public static OpenSans getInstance(Context context) {
synchronized (OpenSans.class) {
if (instance == null) {
instance = new OpenSans();
typeface = Typeface.createFromAsset(context.getResources().getAssets(), "open_sans.ttf");
}
return instance;
}
}
public Typeface getTypeFace() {
return typeface;
}
}
カスタムTextView:
public class NativelyCustomTextView extends TextView {
public NativelyCustomTextView(Context context) {
super(context);
setTypeface(OpenSans.getInstance(context).getTypeFace());
}
public NativelyCustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setTypeface(OpenSans.getInstance(context).getTypeFace());
}
public NativelyCustomTextView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
setTypeface(OpenSans.getInstance(context).getTypeFace());
}
}
Xmlで:
<com.yourpackage.views.NativelyCustomTextView
Android:id="@+id/natively_text_view"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_centerHorizontal="true"
Android:layout_margin="20dp"
Android:text="@string/natively"
Android:textSize="30sp" />
プログラムで:
TextView programmaticallyTextView = (TextView)
findViewById(R.id.programmatically_text_view);
programmaticallyTextView.setTypeface(OpenSans.getInstance(this)
.getTypeFace());
古い質問ですが、良い解決策を自分で探し始める前に、ここでこの答えを読んでください。 Calligraphy は、Android:fontFamily
属性を拡張して、次のようにアセットフォルダーでカスタムフォントのサポートを追加します。
<TextView
Android:text="@string/hello_world"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:fontFamily="fonts/Roboto-Bold.ttf"/>
有効にするために必要なことは、使用しているアクティビティのコンテキストにアタッチすることだけです。
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(new CalligraphyContextWrapper(newBase));
}
Android:fontFamily
を置き換える独自のカスタム属性を指定することもできます
AppThemeなどのテーマでも機能します。
DataBindingを使用:
@BindingAdapter({"bind:font"})
public static void setFont(TextView textView, String fontName){
textView.setTypeface(Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + fontName));
}
XMLの場合:
<TextView
app:font="@{`Source-Sans-Pro-Regular.ttf`}"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"/>
フォントファイルはassets/fonts/
にある必要があります
Android Oプレビューリリースからの最適な方法は、この方法です。
1。)resフォルダーを右クリックして、New> Androidリソースディレクトリ。新しい
リソースディレクトリウィンドウが表示されます。
2。)[リソースタイプ]リストで、fontを選択し、[OK]をクリックします。
3。)フォントフォルダーにフォントファイルを追加します。以下のフォルダー構造により、R.font.dancing_script、R.fontが生成されます。 la_la、およびR.font.ba_ba。
4。)フォントファイルをダブルクリックして、エディターでファイルのフォントをプレビューします。
次に、フォントファミリを作成する必要があります
1.)フォントフォルダを右クリックして、New> Font resource fileに移動します。 [新しいリソースファイル]ウィンドウが表示されます。
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/hey_regular" />
<font
Android:fontStyle="italic"
Android:fontWeight="400"
Android:font="@font/hey_bababa" />
</font-family>
TextViewへのフォントの追加:
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
**Android:fontFamily="@font/ba_ba"**/>
ドキュメントから
すべての手順は正しいです。
追加したい書体が1つだけで、書くコードを減らしたい場合は、特定のフォント専用のTextViewを作成できます。以下のコードを参照してください。
package com.yourpackage;
import Android.content.Context;
import Android.graphics.Typeface;
import Android.util.AttributeSet;
import Android.widget.TextView;
public class FontTextView extends TextView {
public static Typeface FONT_NAME;
public FontTextView(Context context) {
super(context);
if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
this.setTypeface(FONT_NAME);
}
public FontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
this.setTypeface(FONT_NAME);
}
public FontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
this.setTypeface(FONT_NAME);
}
}
Main.xmlで、次のようにtextViewを追加できるようになりました。
<com.yourpackage.FontTextView
Android:id="@+id/tvTimer"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="" />
TextView
を拡張してカスタム属性を指定するか、Android:tag属性を使用して、使用するフォントの文字列を渡します。 TextViewクラスがフォントの場所を認識できるように、すべてのフォントをres/assets/fonts /フォルダーに配置するなど、規則を選択してそれに従う必要があります。次に、コンストラクターで、スーパーコールの後に手動でフォントを設定します。
カスタムフォントを使用する唯一の方法は、ソースコードを使用することです。
Androidはリソースが非常に限られたデバイス上で実行され、フォントには大量のRAMが必要になる場合があることを覚えておいてください。組み込みのDroidフォントは特別に作られており、注意してください、多くの文字と装飾がありません。
TextViewを拡張し、長いコードを実装することなく、質問に対する簡単な答えが得られる場合があります。
コード:
TextView tv = (TextView) findViewById(R.id.textview1);
tv.setTypeface(Typeface.createFromAsset(getAssets(), "font.ttf"));
通常どおりにカスタムフォルダーをアセットフォルダーに配置して、これを試してください。わたしにはできる。ピーターがなぜこの単純なことのためにそんなに大きなコードを与えたのか、古いバージョンで彼が答えを与えたのか、私は理解できません。
カスタムクラスを作成せずにxmlで定義することもできます
style.xml
<style name="ionicons" parent="Android:TextAppearance">
<!-- Custom Attr-->
<item name="fontPath">fonts/ionicons.ttf</item>
</style>
activity_main.xml
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical" >
<Button
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:textAppearance="@style/ionicons"
Android:text=""/>
</LinearLayout>
簡単なメモ、私はいつもフォントを置く場所を忘れていたので、フォントはassets
の中になければならず、このフォルダはres
とsrc
と同じレベルにあり、私の場合はassets/fonts/ionicons.ttf
Updatedこのメソッドが機能するためにはxmlns:app="http://schemas.Android.com/apk/res-auto"
が必要なため、ルートレイアウトを追加しました
Update 2以前にインストールしたライブラリを忘れてしまった Calligraphy
フォントをカスタマイズするには2つの方法があります。
!!! asset/fonts/iran_sans.ttfのカスタムフォント
ウェイ1:反射Typeface.class ||| 最良の方法
クラスのFontsOverride.setDefaultFont()を呼び出してApplicationを拡張します。このコードにより、トーストフォントも含め、すべてのソフトウェアフォントが変更されます。
AppController.Java
public class AppController extends Application {
@Override
public void onCreate() {
super.onCreate();
//Initial Font
FontsOverride.setDefaultFont(getApplicationContext(), "MONOSPACE", "fonts/iran_sans.ttf");
}
}
FontsOverride.Java
public class FontsOverride {
public static void setDefaultFont(Context context, String staticTypefaceFieldName, String fontAssetName) {
final Typeface regular = Typeface.createFromAsset(context.getAssets(), fontAssetName);
replaceFont(staticTypefaceFieldName, regular);
}
private static void replaceFont(String staticTypefaceFieldName, final Typeface newTypeface) {
try {
final Field staticField = Typeface.class.getDeclaredField(staticTypefaceFieldName);
staticField.setAccessible(true);
staticField.set(null, newTypeface);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
方法2: setTypefaceを使用
特別なビューの場合は、setTypeface()を呼び出してフォントを変更します。
CTextView.Java
public class CTextView extends TextView {
public CTextView(Context context) {
super(context);
init(context,null);
}
public CTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context,attrs);
}
public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context,attrs);
}
@RequiresApi(api = Build.VERSION_CODES.Lollipop)
public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context,attrs);
}
public void init(Context context, @Nullable AttributeSet attrs) {
if (isInEditMode())
return;
// use setTypeface for change font this view
setTypeface(FontUtils.getTypeface("fonts/iran_sans.ttf"));
}
}
FontUtils.Java
public class FontUtils {
private static Hashtable<String, Typeface> fontCache = new Hashtable<>();
public static Typeface getTypeface(String fontName) {
Typeface tf = fontCache.get(fontName);
if (tf == null) {
try {
tf = Typeface.createFromAsset(AppController.getInstance().getApplicationContext().getAssets(), fontName);
} catch (Exception e) {
e.printStackTrace();
return null;
}
fontCache.put(fontName, tf);
}
return tf;
}
}
Peterの答えは最高ですが、Androidのstyles.xmlを使用して、アプリのすべてのテキストビューのフォントをカスタマイズすることで改善できます。
私のコードは ここ です
以下に、@ peterのようなカスタムフォントを設定する方法を説明するチュートリアルを示します。 http://responsiveandroid.com/2012/03/15/custom-fonts-in-Android-widgets.html
潜在的なメモリリークについても考慮していますala http://code.google.com/p/Android/issues/detail?id=9904 チュートリアルには、ボタンにカスタムフォントを設定する例もあります。
あなたは簡単にカスタムtextviewクラスを作成できます:
最初に行う必要があるのは、AppCompatTextView
で拡張されたCustom textview
クラスを作成することです。
public class CustomTextView extends AppCompatTextView {
private int mFont = FontUtils.FONTS_NORMAL;
boolean fontApplied;
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, context);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, context);
}
public CustomTextView(Context context) {
super(context);
init(null, context);
}
protected void init(AttributeSet attrs, Context cxt) {
if (!fontApplied) {
if (attrs != null) {
mFont = attrs.getAttributeIntValue(
"http://schemas.Android.com/apk/res-auto", "Lato-Regular.ttf",
-1);
}
Typeface typeface = getTypeface();
int typefaceStyle = Typeface.NORMAL;
if (typeface != null) {
typefaceStyle = typeface.getStyle();
}
if (mFont > FontUtils.FONTS) {
typefaceStyle = mFont;
}
FontUtils.applyFont(this, typefaceStyle);
fontApplied = true;
}
}
}
これで、カスタムテキストビューが呼び出されるたびに、属性int fontValue = attrs.getAttributeIntValue("http://schemas.Android.com/apk/res-auto","Lato-Regular.ttf",-1)
からint値を取得します。
または
また、xml(Android:textStyle="bold|normal|italic"
)で設定したビューからgetTypeface()を取得することもできます。だからあなたがやりたいことをやる。
次に、.ttfフォントをビューに設定するためのFontUtils
を作成します。
public class FontUtils {
public static final int FONTS = 1;
public static final int FONTS_NORMAL = 2;
public static final int FONTS_BOLD = 3;
public static final int FONTS_BOLD1 = 4;
private static Map<String, Typeface> TYPEFACE = new HashMap<String, Typeface>();
static Typeface getFonts(Context context, String name) {
Typeface typeface = TYPEFACE.get(name);
if (typeface == null) {
typeface = Typeface.createFromAsset(context.getAssets(), name);
TYPEFACE.put(name, typeface);
}
return typeface;
}
public static void applyFont(TextView tv, int typefaceStyle) {
Context cxt = tv.getContext();
Typeface typeface;
if(typefaceStyle == Typeface.BOLD_ITALIC) {
typeface = FontUtils.getFonts(cxt, "FaktPro-Normal.ttf");
}else if (typefaceStyle == Typeface.BOLD || typefaceStyle == SD_FONTS_BOLD|| typefaceStyle == FONTS_BOLD1) {
typeface = FontUtils.getFonts(cxt, "FaktPro-SemiBold.ttf");
} else if (typefaceStyle == Typeface.ITALIC) {
typeface = FontUtils.getFonts(cxt, "FaktPro-Thin.ttf");
} else {
typeface = FontUtils.getFonts(cxt, "FaktPro-Normal.ttf");
}
if (typeface != null) {
tv.setTypeface(typeface);
}
}
}
Android 8.0(APIレベル26)以降では XMLでカスタムフォントを使用 が可能であることを知っておくと役立つ場合があります。
次の方法で、アプリケーション全体にカスタムフォントを適用できます。
フォントをフォルダーres/font
に入れます。
res/values/styles.xml
では、アプリケーションテーマで使用します。 <style name="AppTheme" parent="{whatever you like}"> <item name="Android:fontFamily">@font/myfont</item> </style>