전체 응용 프로그램에 특정 글꼴을 사용해야합니다. 동일한 .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");
}
}
또는 동일한 글꼴 파일을 사용하는 경우이를 개선하여 한 번만로드 할 수 있습니다.
그러나 나는 하나를 무시 "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>
TextView
사용자 정의 글꼴을 사용하거나 이와 같은 리플렉션 기반 솔루션을 사용하기 위해 모든 곳 에서 기본값을 바꾸어야한다는 것은 정말 성가신 일 입니다. 안드로이드에서 사용할 수있는 제한적인 글꼴 세트와 결합하여 멋진 앱을 개발하는 데 많은 노력을 기울입니다. Android 이슈 트래커에 기능 요청을 추가했습니다. 이 기능을보고 싶다면 code.google.com/p/android/issues/…
안드로이드에는 커스텀 폰트를위한 훌륭한 라이브러리가 있습니다 : Calligraphy
다음은 사용 방법에 대한 샘플입니다.
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();
}
}
}
}
응용 프로그램 클래스의 사용법 :
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>
Option2 : 폰트를 커스터마이즈해야하는 각각의 모든 뷰를 서브 클래 싱 합니다. 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 ( Tom 의 답변) :
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 라는 타사 라이브러리를 사용하십시오 .
개인적으로, 옵션 # 4는 많은 두통을 덜기 때문에 권장합니다.
"sans-serif"
에서 newMap.put(
, 그리고 monospace
에 styles
?! 이름이 커스텀 글꼴을 사용하고 싶습니다 barana.ttf
.
웨스턴 을 개선하고 싶습니다API 21 Android 5.0에 대한 의 답변 .
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 속성 ( reference 보다 우선 순위가 높기 때문에 원래의 대답은 고정 폭 글꼴을 적용하지 못합니다. ) . 내부에 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
및 도구 모음 제목 에서 작동하지 않는지 궁금 합니다. MainApplication의 기본 글꼴을 다음과 같이 재정의하고 FontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");
있습니다. Nexus 5, v5.1.1을 사용하고 있습니다.
Build.VERSION.SDK_INT == 21
- API 21
API 22를 사용하여 Nexus에서 테스트
그것의 아주 간단한 ... 1. 다운로드 및 자산에 ur 사용자 정의 글꼴을 넣습니다. 다음 텍스트 뷰에 대해 별도의 클래스를 하나 작성하십시오 : 여기에 나는 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 의 답변 을 개선하고 싶습니다 .
안드로이드 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 파일 폴더의 유틸리티는 무엇에서와 동일 웨스턴 의 대답. 이 전화에서 테스트했습니다.
Nexus 5 (Android 5.1 기본 Android 시스템)
ZTE V5 (Android 5.1 CM12.1)
XIAOMI 노트 (Android 4.4 MIUI6)
화웨이 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)에서 작동하는 코드를 작성했습니다. https://stackoverflow.com/a/33236102/2914140 뿐만 아니라 weston 및 Roger Huang의 코드를 사용했습니다 . 또한 작동하지 않는 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();
'자산'내에 '글꼴'폴더를 만들고 필요한 글꼴을 거기에 넣으십시오. 간단한 지침은 https://stackoverflow.com/a/31697103/2914140 에서 찾을 수 있습니다 .
Lenovo 장치도 서체 값을 잘못 얻습니다. 대부분의 경우 Typeface.NORMAL, 때로는 null을 반환합니다. xml 파일 레이아웃에서 TextView가 굵게 표시 되더라도. 여기를 참조하십시오 : 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>
즐겨!
루트 뷰를 전달하여 모든 레이아웃에서 하나의 함수 호출만으로 모든 레이아웃에 대해 사용자 정의 글꼴을 하나씩 설정할 수 있습니다. 먼저 다음과 같은 글꼴 개체에 액세스하기위한 단일 방법을 만듭니다.
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는 "주 부모"이며 이제 글꼴을 적용 할 수 있습니다
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);
}
Tom의 솔루션은 훌륭하게 작동하지만 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 dependecies에서 이것을 사용하십시오.
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 대신 앱 네임 스페이스를 사용해야합니다!
API 21 Android 5.0에 대한 weston의 답변을 향상시키고 싶습니다.
DEFAULT 글꼴을 사용할 때 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 라이브러리 와 코더 월의 게시물 이 혼합 된 결과를 내 궁극적 인 결과로 찾았습니다 .
예, 글꼴을 전체 응용 프로그램으로 설정할 수 있습니다.
가장 쉬운 방법은 원하는 글꼴을 응용 프로그램과 함께 패키지하는 것입니다.
이렇게하려면 간단히 자산 / 프로젝트 루트에 폴더를 글꼴 (TrueType 또는 TTF 형식)을 자산에 넣으십시오.
예를 들어, asset / 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);
}
}