アプリケーション全体で特定のフォントを使用する必要があります。同じための.ttfファイルがあります。アプリケーションの起動時にこれをデフォルトのフォントとして設定して、アプリケーションの他の場所で使用することはできますか?設定した場合、レイアウトXMLでどのように使用しますか?
アプリケーション全体で特定のフォントを使用する必要があります。同じための.ttfファイルがあります。アプリケーションの起動時にこれをデフォルトのフォントとして設定して、アプリケーションの他の場所で使用することはできますか?設定した場合、レイアウトXMLでどのように使用しますか?
回答:
はい、反射があります。これは機能します(この回答に基づく):
(注:カスタムフォントのサポートが不足しているため、これは回避策です。この状況を変更したい場合は、スターを付けてAndroidの問題をここで投票してください)。注:その問題について「私も」というコメントを残さないでください。それを開始した人は全員、メールを受け取ります。だから「星」だけにしてください。
import java.lang.reflect.Field;
import android.content.Context;
import android.graphics.Typeface;
public final class FontsOverride {
public static void setDefaultFont(Context context,
String staticTypefaceFieldName, String fontAssetName) {
final Typeface regular = Typeface.createFromAsset(context.getAssets(),
fontAssetName);
replaceFont(staticTypefaceFieldName, regular);
}
protected 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();
}
}
}
次に、たとえばアプリケーションクラスで、いくつかのデフォルトフォントをオーバーロードする必要があります。
public final class Application extends android.app.Application {
@Override
public void onCreate() {
super.onCreate();
FontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "MyFontAsset2.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "MyFontAsset3.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "MyFontAsset4.ttf");
}
}
または、同じフォントファイルを使用している場合は、これを改善して一度だけロードすることができます。
ただし、私は1つをオーバーライドする傾向があります。たとえば"MONOSPACE"
、フォントの書体をアプリケーション全体に強制するスタイルを設定します。
<resources>
<style name="AppBaseTheme" parent="android:Theme.Light">
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:typeface">monospace</item>
</style>
</resources>
コメントでレポートが機能しない、およびテーマと互換性がないように思われるという報告を調査しましたandroid:Theme.Material.Light
。
そのテーマが重要でない場合は、古いテーマを使用してください。例:
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:typeface">monospace</item>
</style>
"DEFAULT_BOLD"
プライベートフィールドもあります。private static Typeface[] sDefaults;
リフレクションとsDefaults[Typeface.ITALIC]
yourTypefaceへの設定により、これにアクセスできます。これを
TextView
カスタムフォントを使用したり、このようなリフレクションベースのソリューションを使用したりするために、どこでもデフォルトを交換しなければならないのは本当に面倒です。Androidで使用できるフォントの制限セットと組み合わせると、見栄えの良いアプリの開発は大変な労力になります。Androidの課題追跡に機能リクエストを追加しました。この機能をご覧になりたい場合は、code.google.com
Androidにはカスタムフォント用の素晴らしいライブラリがあります:書道
使い方のサンプルはこちらです。
Gradleでは、次の行をアプリのbuild.gradleファイルに追加する必要があります。
dependencies {
compile 'uk.co.chrisjenx:calligraphy:2.2.0'
}
次に、Application
このコードを拡張して記述するクラスを作成します。
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
.setDefaultFontPath("your font path")
.setFontAttrId(R.attr.fontPath)
.build()
);
}
}
アクティビティクラスでは、このメソッドをonCreateの前に配置します。
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}
そして最後にマニフェストファイルは次のようになります。
<application
.
.
.
android:name=".App">
アクティビティ全体がフォントに変更されます!シンプルできれいです!
<b></b>
に、私はを使用<u></u>
し<i></i>
ましたが、strings.xml
ファイル内ではこれまでのところ機能します。
これはアプリケーション全体では機能しませんが、アクティビティで機能し、他のアクティビティで再利用できます。@ FR073Nのおかげで、他のビューをサポートするようにコードを更新しました。これらのクラスはすべて拡張されているためButtons
、問題なく動作するはずなのでRadioGroups
、、、などの問題についてはわかりませんTextView
。リフレクションを使用するためのブール条件を追加しました。これは非常にハックに見え、特にパフォーマンスが低下する可能性があるためです。
注:指摘したように、これは動的コンテンツでは機能しません!そのため、このメソッドを、たとえばonCreateView
or getView
メソッドで呼び出すことは可能ですが、追加の作業が必要です。
/**
* Recursively sets a {@link Typeface} to all
* {@link TextView}s in a {@link ViewGroup}.
*/
public static final void setAppFont(ViewGroup mContainer, Typeface mFont, boolean reflect)
{
if (mContainer == null || mFont == null) return;
final int mCount = mContainer.getChildCount();
// Loop through all of the children.
for (int i = 0; i < mCount; ++i)
{
final View mChild = mContainer.getChildAt(i);
if (mChild instanceof TextView)
{
// Set the font if it is a TextView.
((TextView) mChild).setTypeface(mFont);
}
else if (mChild instanceof ViewGroup)
{
// Recursively attempt another ViewGroup.
setAppFont((ViewGroup) mChild, mFont);
}
else if (reflect)
{
try {
Method mSetTypeface = mChild.getClass().getMethod("setTypeface", Typeface.class);
mSetTypeface.invoke(mChild, mFont);
} catch (Exception e) { /* Do something... */ }
}
}
}
それを使用するには、次のようにします。
final Typeface mFont = Typeface.createFromAsset(getAssets(),
"fonts/MyFont.ttf");
final ViewGroup mContainer = (ViewGroup) findViewById(
android.R.id.content).getRootView();
HomeActivity.setAppFont(mContainer, mFont);
お役に立てば幸いです。
要約すれば:
オプション#1: リフレクションを使用してフォントを適用する(westonとRoger Huangの回答を組み合わせたもの):
import java.lang.reflect.Field;
import android.content.Context;
import android.graphics.Typeface;
public final class FontsOverride {
public static void setDefaultFont(Context context,
String staticTypefaceFieldName, String fontAssetName) {
final Typeface regular = Typeface.createFromAsset(context.getAssets(),
fontAssetName);
replaceFont(staticTypefaceFieldName, regular);
}
protected static void replaceFont(String staticTypefaceFieldName,final Typeface newTypeface) {
if (isVersionGreaterOrEqualToLollipop()) {
Map<String, Typeface> newMap = new HashMap<String, Typeface>();
newMap.put("sans-serif", newTypeface);
try {
final Field staticField = Typeface.class.getDeclaredField("sSystemFontMap");
staticField.setAccessible(true);
staticField.set(null, newMap);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
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();
}
}
}
}
Applicationクラスでの使用:
public final class Application extends android.app.Application {
@Override
public void onCreate() {
super.onCreate();
FontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "MyFontAsset2.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "MyFontAsset3.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "MyFontAsset4.ttf");
}
}
そのフォントタイプフェイスアプリケーションを強制的に広くするスタイルを設定します(lovefishに基づく))。
プレロリポップ:
<resources>
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:typeface">monospace</item>
</style>
</resources>
ロリポップ(API 21):
<resources>
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:textAppearance">@style/CustomTextAppearance</item>
</style>
<style name="CustomTextAppearance">
<item name="android:typeface">monospace</item>
</style>
</resources>
オプション2: フォントをカスタマイズする必要があるすべてのビューをサブクラス化します。ListView、EditTextView、Buttonなど(Palaniの答え):
public class CustomFontView extends TextView {
public CustomFontView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public CustomFontView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomFontView(Context context) {
super(context);
init();
}
private void init() {
if (!isInEditMode()) {
Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "Futura.ttf");
setTypeface(tf);
}
}
オプション3: 現在の画面のビュー階層を移動するビュークローラーを実装します。
バリエーション#1(トムの答え):
public static final void setAppFont(ViewGroup mContainer, Typeface mFont, boolean reflect)
{
if (mContainer == null || mFont == null) return;
final int mCount = mContainer.getChildCount();
// Loop through all of the children.
for (int i = 0; i < mCount; ++i)
{
final View mChild = mContainer.getChildAt(i);
if (mChild instanceof TextView)
{
// Set the font if it is a TextView.
((TextView) mChild).setTypeface(mFont);
}
else if (mChild instanceof ViewGroup)
{
// Recursively attempt another ViewGroup.
setAppFont((ViewGroup) mChild, mFont);
}
else if (reflect)
{
try {
Method mSetTypeface = mChild.getClass().getMethod("setTypeface", Typeface.class);
mSetTypeface.invoke(mChild, mFont);
} catch (Exception e) { /* Do something... */ }
}
}
}
使用法 :
final ViewGroup mContainer = (ViewGroup) findViewById(
android.R.id.content).getRootView();
HomeActivity.setAppFont(mContainer, Typeface.createFromAsset(getAssets(),
"fonts/MyFont.ttf"));
バリエーション#2:https : //coderwall.com/p/qxxmaa/android-use-a-custom-font-everywhere。
オプション#4:Calligraphy と呼ばれるサードパーティのLibを使用します。
個人的に、私はOption#4をお勧めします。
"sans-serif"
でnewMap.put(
、とmonospace
にstyles
?!という名前のカスタムフォントを使用したいbarana.ttf
。
API 21 Android 5.0に対するwestonの回答を改善したいと思います。
API 21では、ほとんどのテキストスタイルに次のようなfontFamily設定が含まれています。
<style name="TextAppearance.Material">
<item name="fontFamily">@string/font_family_body_1_material</item>
</style>
デフォルトのRoboto Regularフォントが適用されます。
<string name="font_family_body_1_material">sans-serif</string>
android:fontFamilyはandroid:typeface属性よりも優先度が高いため、元の回答ではモノスペースフォントを適用できません(参照)。内部にはandroid:fontFamily設定がないため、Theme.Holo。*の使用は有効な回避策です。
Android 5.0では、システムの書体を静的変数Typeface.sSystemFontMap(reference)に入れているため、同じリフレクションテクニックを使用して置き換えることができます。
protected static void replaceFont(String staticTypefaceFieldName,
final Typeface newTypeface) {
if (isVersionGreaterOrEqualToLollipop()) {
Map<String, Typeface> newMap = new HashMap<String, Typeface>();
newMap.put("sans-serif", newTypeface);
try {
final Field staticField = Typeface.class
.getDeclaredField("sSystemFontMap");
staticField.setAccessible(true);
staticField.set(null, newMap);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
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();
}
}
}
Button
のsとTool Barのタイトルで機能しないように見えるのでしょうか。MainApplicationのデフォルトフォントを次のようにオーバーライドしていますFontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");
。私はNexus 5、v5.1.1を使用しています
Build.VERSION.SDK_INT == 21
API 21
その非常に単純な... 1. urカスタムフォントをダウンロードしてアセットに配置します。次に、テキストビュー用に1つの個別のクラスを次のように記述します。ここではfuturaフォントを使用しました
public class CusFntTextView extends TextView {
public CusFntTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public CusFntTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CusFntTextView(Context context) {
super(context);
init();
}
private void init() {
if (!isInEditMode()) {
Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "Futura.ttf");
setTypeface(tf);
}
}
}
そして、xmlで次のようにします:
<com.packagename.CusFntTextView
android:id="@+id/tvtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hi Android"
android:textAppearance="?android:attr/textAppearanceLarge"
/>
また、TextViewやその他のコントロールを拡張することをお勧めしますが、構造体にフォントを設定することを検討する方が良いでしょう。
public FontTextView(Context context) {
super(context);
init();
}
public FontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public FontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
protected void init() {
setTypeface(Typeface.createFromAsset(getContext().getAssets(), AppConst.FONT));
}
テーマ「Theme.AppCompat」を使用して、API 21 Androidのロリポップ以上のwestonとRoger Huangの回答を改善したいと思います。
Android 4.4未満
<resources>
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:typeface">monospace</item>
</style>
</resources>
(等しい)API 5.0以上
<resources>
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:textAppearance">@style/CustomTextAppearance</item>
</style>
<style name="CustomTextAppearance">
<item name="android:typeface">monospace</item>
</style>
</resources>
そして、FontsOverride utilファイルはwestonの回答と同じです。私はこれらの電話でテストしました:
Nexus 5(android 5.1プライマリAndroidシステム)
ZTE V5(android 5.1 CM12.1)
XIAOMIノート(android 4.4 MIUI6)
HUAWEI C8850(android 2.3.5 UNKNOWN)
素晴らしいソリューションはここにあります:https : //coderwall.com/p/qxxmaa/android-use-a-custom-font-everywhere。
BaseActivityからアクティビティを拡張し、それらのメソッドを記述するだけです。また、https://stackoverflow.com/a/16902532/2914140で説明されているように、フォントをより適切にキャッシュする必要があります。
いくつかの調査の後、Samsung Galaxy Tab A(Android 5.0)で動作するコードを書きました。westonとRoger Huangのコードとhttps://stackoverflow.com/a/33236102/2914140を使用しました。また、動作しないLenovo TAB 2 A10-70Lでもテストされています。違いを見るために、ここに「Comic Sans」というフォントを挿入しました。
import android.content.Context;
import android.graphics.Typeface;
import android.os.Build;
import android.util.Log;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class FontsOverride {
private static final int BOLD = 1;
private static final int BOLD_ITALIC = 2;
private static final int ITALIC = 3;
private static final int LIGHT = 4;
private static final int CONDENSED = 5;
private static final int THIN = 6;
private static final int MEDIUM = 7;
private static final int REGULAR = 8;
private Context context;
public FontsOverride(Context context) {
this.context = context;
}
public void loadFonts() {
Map<String, Typeface> fontsMap = new HashMap<>();
fontsMap.put("sans-serif", getTypeface("comic.ttf", REGULAR));
fontsMap.put("sans-serif-bold", getTypeface("comic.ttf", BOLD));
fontsMap.put("sans-serif-italic", getTypeface("comic.ttf", ITALIC));
fontsMap.put("sans-serif-light", getTypeface("comic.ttf", LIGHT));
fontsMap.put("sans-serif-condensed", getTypeface("comic.ttf", CONDENSED));
fontsMap.put("sans-serif-thin", getTypeface("comic.ttf", THIN));
fontsMap.put("sans-serif-medium", getTypeface("comic.ttf", MEDIUM));
overrideFonts(fontsMap);
}
private void overrideFonts(Map<String, Typeface> typefaces) {
if (Build.VERSION.SDK_INT == 21) {
try {
final Field field = Typeface.class.getDeclaredField("sSystemFontMap");
field.setAccessible(true);
Map<String, Typeface> oldFonts = (Map<String, Typeface>) field.get(null);
if (oldFonts != null) {
oldFonts.putAll(typefaces);
} else {
oldFonts = typefaces;
}
field.set(null, oldFonts);
field.setAccessible(false);
} catch (Exception e) {
Log.e("TypefaceUtil", "Cannot set custom fonts");
}
} else {
try {
for (Map.Entry<String, Typeface> entry : typefaces.entrySet()) {
final Field staticField = Typeface.class.getDeclaredField(entry.getKey());
staticField.setAccessible(true);
staticField.set(null, entry.getValue());
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
private Typeface getTypeface(String fontFileName, int fontType) {
final Typeface tf = Typeface.createFromAsset(context.getAssets(), "fonts/" + fontFileName);
return Typeface.create(tf, fontType);
}
}
アプリケーション全体でコードを実行するには、Applicationのようなクラスに次のように記述する必要があります。
new FontsOverride(this).loadFonts();
「assets」内に「fonts」フォルダを作成し、そこに必要なフォントを配置します。簡単な指示はここにあります:https : //stackoverflow.com/a/31697103/2914140。
Lenovoデバイスも、書体の値を誤って取得します。ほとんどの場合、それはTypeface.NORMALを返し、時にはnullを返します。TextViewが太字の場合でも(xmlファイルレイアウト)。ここを参照してください:TextView isBoldは常にNORMALを返します。このようにして、画面上のテキストは常に太字や斜体ではなく通常のフォントになります。だからプロデューサーのバグだと思う。
Xamarin.Androidでの作業:
クラス:
public class FontsOverride
{
public static void SetDefaultFont(Context context, string staticTypefaceFieldName, string fontAssetName)
{
Typeface regular = Typeface.CreateFromAsset(context.Assets, fontAssetName);
ReplaceFont(staticTypefaceFieldName, regular);
}
protected static void ReplaceFont(string staticTypefaceFieldName, Typeface newTypeface)
{
try
{
Field staticField = ((Java.Lang.Object)(newTypeface)).Class.GetDeclaredField(staticTypefaceFieldName);
staticField.Accessible = true;
staticField.Set(null, newTypeface);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
アプリケーションの実装:
namespace SomeAndroidApplication
{
[Application]
public class App : Application
{
public App()
{
}
public App(IntPtr handle, JniHandleOwnership transfer)
: base(handle, transfer)
{
}
public override void OnCreate()
{
base.OnCreate();
FontsOverride.SetDefaultFont(this, "MONOSPACE", "fonts/Roboto-Light.ttf");
}
}
}
スタイル:
<style name="Theme.Storehouse" parent="Theme.Sherlock">
<item name="android:typeface">monospace</item>
</style>
Android O以降、これはXMLから直接定義できるようになり、私のバグはクローズされました!
TL; DR:
まず、プロジェクトにフォントを追加する必要があります
次に、次のようにフォントファミリーを追加します。
<?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>
最後に、フォントをレイアウトまたはスタイルで使用できます。
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/lobster"/>
<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
<item name="android:fontFamily">@font/lobster</item>
</style>
楽しい!
すべてのレイアウトのカスタムフォントを1つずつ設定できます。ルートのViewを渡すことにより、すべてのレイアウトから関数を1回呼び出すだけです。最初に、このようなフォントオブジェクトにアクセスするためのシングルトンアプローチを作成します。
public class Font {
private static Font font;
public Typeface ROBO_LIGHT;
private Font() {
}
public static Font getInstance(Context context) {
if (font == null) {
font = new Font();
font.init(context);
}
return font;
}
public void init(Context context) {
ROBO_LIGHT = Typeface.createFromAsset(context.getAssets(),
"Roboto-Light.ttf");
}
}
上記のクラスでさまざまなフォントを定義できます。次に、フォントを適用するフォントヘルパークラスを定義します。
public class FontHelper {
private static Font font;
public static void applyFont(View parentView, Context context) {
font = Font.getInstance(context);
apply((ViewGroup)parentView);
}
private static void apply(ViewGroup parentView) {
for (int i = 0; i < parentView.getChildCount(); i++) {
View view = parentView.getChildAt(i);
//You can add any view element here on which you want to apply font
if (view instanceof EditText) {
((EditText) view).setTypeface(font.ROBO_LIGHT);
}
if (view instanceof TextView) {
((TextView) view).setTypeface(font.ROBO_LIGHT);
}
else if (view instanceof ViewGroup
&& ((ViewGroup) view).getChildCount() > 0) {
apply((ViewGroup) view);
}
}
}
}
上記のコードでは、textViewとEditTextのみにフォントを適用していますが、他のビュー要素にも同様にフォントを適用できます。ルートビューグループのIDを上記のフォント適用メソッドに渡すだけです。例えばあなたのレイアウトは:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/mainParent"
tools:context="${relativePackage}.${activityClass}" >
<RelativeLayout
android:id="@+id/mainContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/homeFooter"
android:layout_below="@+id/edit" >
<ImageView
android:id="@+id/PreviewImg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/abc_list_longpressed_holo"
android:visibility="gone" />
<RelativeLayout
android:id="@+id/visibilityLayer"
android:layout_width="match_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="@+id/UseCamera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:src="@drawable/camera" />
<TextView
android:id="@+id/tvOR"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/UseCamera"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="OR"
android:textSize="30dp" />
<TextView
android:id="@+id/tvAND"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="OR"
android:textSize="30dp" />
</RelativeLayout>
上記のレイアウトでは、ルートの親IDは「Main Parent」になり、フォントを適用できるようになりました
public class MainActivity extends BaseFragmentActivity {
private EditText etName;
private EditText etPassword;
private TextView tvTitle;
public static boolean isHome = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Font font=Font.getInstance(getApplicationContext());
FontHelper.applyFont(findViewById(R.id.mainParent), getApplicationContext());
}
}
乾杯:)
TextViewを拡張し、XMLレイアウト内またはTextViewが必要な場所では常にカスタムTextViewを使用することをお勧めします。カスタムTextViewで、オーバーライドsetTypeface
@Override
public void setTypeface(Typeface tf, int style) {
//to handle bold, you could also handle italic or other styles here as well
if (style == 1){
tf = Typeface.createFromAsset(getContext().getApplicationContext().getAssets(), "MuseoSans700.otf");
}else{
tf = Typeface.createFromAsset(getContext().getApplicationContext().getAssets(), "MuseoSans500.otf");
}
super.setTypeface(tf, 0);
}
トムのソリューションはうまく機能しますが、TextViewとEditTextでのみ機能します。
ほとんどのビュー(RadioGroup、TextView、Checkbox ...)をカバーしたい場合は、それを行うメソッドを作成しました。
protected void changeChildrenFont(ViewGroup v, Typeface font){
for(int i = 0; i < v.getChildCount(); i++){
// For the ViewGroup, we'll have to use recursivity
if(v.getChildAt(i) instanceof ViewGroup){
changeChildrenFont((ViewGroup) v.getChildAt(i), font);
}
else{
try {
Object[] nullArgs = null;
//Test wether setTypeface and getTypeface methods exists
Method methodTypeFace = v.getChildAt(i).getClass().getMethod("setTypeface", new Class[] {Typeface.class, Integer.TYPE});
//With getTypefaca we'll get back the style (Bold, Italic...) set in XML
Method methodGetTypeFace = v.getChildAt(i).getClass().getMethod("getTypeface", new Class[] {});
Typeface typeFace = ((Typeface)methodGetTypeFace.invoke(v.getChildAt(i), nullArgs));
//Invoke the method and apply the new font with the defined style to the view if the method exists (textview,...)
methodTypeFace.invoke(v.getChildAt(i), new Object[] {font, typeFace == null ? 0 : typeFace.getStyle()});
}
//Will catch the view with no such methods (listview...)
catch (Exception e) {
e.printStackTrace();
}
}
}
}
このメソッドは、XMLで設定されたビューのスタイル(太字、斜体...)を取得し、存在する場合は適用します。
ListViewの場合は、常にアダプターを作成し、getView内にフォントを設定します。
現在のビュー階層のビューにタイプフェイスを割り当てるクラスを作成し、現在のタイプフェイスプロパティに基づいています(太字、通常、必要に応じて他のスタイルを追加できます)。
public final class TypefaceAssigner {
public final Typeface DEFAULT;
public final Typeface DEFAULT_BOLD;
@Inject
public TypefaceAssigner(AssetManager assetManager) {
DEFAULT = Typeface.createFromAsset(assetManager, "TradeGothicLTCom.ttf");
DEFAULT_BOLD = Typeface.createFromAsset(assetManager, "TradeGothicLTCom-Bd2.ttf");
}
public void assignTypeface(View v) {
if (v instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) v).getChildCount(); i++) {
View view = ((ViewGroup) v).getChildAt(i);
if (view instanceof ViewGroup) {
setTypeface(view);
} else {
setTypeface(view);
}
}
} else {
setTypeface(v);
}
}
private void setTypeface(View view) {
if (view instanceof TextView) {
TextView textView = (TextView) view;
Typeface typeface = textView.getTypeface();
if (typeface != null && typeface.isBold()) {
textView.setTypeface(DEFAULT_BOLD);
} else {
textView.setTypeface(DEFAULT);
}
}
}
}
onViewCreatedまたはonCreateViewのすべてのフラグメント、onCreateのすべてのアクティビティ、およびgetViewまたはnewViewのすべてのビューアダプターで、次のように呼び出します。
typefaceAssigner.assignTypeface(view);
build.gradle 3.0.0以降のAPI 26では、resにフォントディレクトリを作成し、この行をスタイルで使用できます
<item name="android:fontFamily">@font/your_font</item>
build.gradleを変更するには、build.gradle依存関係でこれを使用します
classpath 'com.android.tools.build:gradle:3.0.0'
item
だけではアプリ全体のフォントは設定されません。どんな手掛かり?
最後に、Googleはこの問題の深刻さ(カスタムフォントをUIコンポーネントに適用すること)を認識し、そのためのクリーンなソリューションを考案しました。
まず、ライブラリ26+をサポートするように更新する必要があります(gradle {4.0 +}、android studioも更新する必要がある場合があります)。次に、fontという新しいリソースフォルダーを作成できます。このフォルダに、フォントリソース(.tff、...)を置くことができます。次に、デフォルトのアプリをオーバーライドして、カスタムフォントを強制する必要があります:)
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:fontFamily">@font/my_custom_font</item>
</style>
注:16より古いAPIのデバイスをサポートする場合は、androidではなくapp名前空間を使用する必要があります!
また、API 21 Android 5.0に対するwestonの回答を改善したいと思います。
デフォルトのフォントを使用すると、Samsung s5でも同じ問題が発生しました。(他のフォントではうまく機能しています)
TextviewまたはButtonごとに、XMLファイルで書体(「sans」など)を設定することで、それを機能させることができました
<TextView
android:layout_width="match_parent"
android:layout_height="39dp"
android:textColor="@color/abs__background_holo_light"
android:textSize="12sp"
android:gravity="bottom|center"
android:typeface="sans" />
MyApplicationクラス:
public class MyApplication extends Application {
@Override
public void onCreate() {
TypefaceUtil.overrideFont(getApplicationContext(), "SANS_SERIF",
"fonts/my_font.ttf");
}
}
それが役に立てば幸い。
このソリューションは、状況によっては正しく機能しません。
だから私はそれを拡張します:
FontsReplacer.java
public class MyApplication extends Application {
@Override
public void onCreate() {
FontsReplacer.replaceFonts(this);
super.onCreate();
}
}
https://gist.github.com/orwir/6df839e3527647adc2d56bfadfaad805
書道はかなりうまく機能しますが、フォントファミリの異なる太さ(太字、斜体など)をサポートしていないため、筆者には適していません。
そこで私はFontainを試してみました。これにより、カスタムビューを定義し、それらにカスタムフォントファミリーを適用できます。
Fontainを使用するには、アプリモジュールbuild.gradleに以下を追加する必要があります。
compile 'com.scopely:fontain:1.0.0'
次に、通常のTextViewを使用する代わりに、FontTextViewを使用する必要があります
大文字と太字のコンテンツを含むFontTextViewの例:
<com.scopely.fontain.views.FontTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/black"
android:textColor="@android:color/white"
android:textSize="11dp"
android:gravity="center"
android:id="@+id/tv1"
app:font_family="myCustomFont"
app:caps_mode="characters"
app:font_weight="BOLD"/>
package com.theeasylearn.demo.designdemo;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;
public class MyButton extends TextView {
public MyButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyButton(Context context) {
super(context);
init();
}
private void init() {
Typeface tf =
Typeface.createFromAsset(
getContext().getAssets(), "angelina.TTF");
setTypeface(tf);
}
}
TextView
S
TextViewのデフォルトのフォントファミリーを変更するには、アプリのテーマでtextViewStyleをオーバーライドします。
fontFamilyでカスタムフォントを使用するには、サポートライブラリにあるフォントリソースを使用します。
この機能はAndroid 26で追加されましたが、supportlibを介して古いバージョンにバックポートされました。
https://developer.android.com/guide/topics/resources/font-resource.html https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html #using-support-lib
最終的な結果として、書道3のライブラリとcoderwallの投稿が混在していることがわかりました。
はい、フォントをアプリケーション全体に設定することは可能です。
これを実現する最も簡単な方法は、目的のフォントをアプリケーションにパッケージ化することです。
これを行うに は、プロジェクトのルートにassets /フォルダーを作成し、フォント(TrueTypeまたはTTF形式)をアセットに配置します。
たとえば、assets / fonts / を作成して、そこにTTFファイルを置くことができます。
public class FontSampler extends Activity {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
TextView tv=(TextView)findViewById(R.id.custom);
Typeface face=Typeface.createFromAsset(getAssets(), "fonts/HandmadeTypewriter.ttf");
tv.setTypeface(face);
}
}