전체 응용 프로그램에 특정 글꼴을 사용해야합니다. 동일한 .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>
API 21 안드로이드 5.0
작동하지 않는다는 의견의 보고서를 조사했으며 테마와 호환되지 않는 것으로 보입니다. android:Theme.Material.Light
.
해당 테마가 중요하지 않은 경우 다음과 같은 이전 테마를 사용하십시오.
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:typeface">monospace</item>
</style>
답변
안드로이드에는 커스텀 폰트를위한 훌륭한 라이브러리가 있습니다 : 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">
전체 활동을 글꼴로 변경합니다! 간단하고 깨끗합니다!
답변
전체 응용 프로그램에서는 작동하지 않지만 활동에서는 작동하고 다른 활동에서는 재사용 할 수 있습니다. 다른 뷰를 지원하기 위해 @ 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는 많은 두통을 덜기 때문에 권장합니다.
답변
웨스턴 을 개선하고 싶습니다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();
}
}
}
답변
그것의 아주 간단한 … 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));
}