Android에서 사용자 지정 서체 사용
제가 만들고 있는 안드로이드 어플리케이션에 커스텀 폰트를 사용하고 싶습니다.
나는 코드에서 각 개체의 서체를 개별적으로 변경할 수 있지만 수백 개의 서체를 가지고 있습니다.
그렇게,
- XML에서 이 작업을 수행할 수 있는 방법이 있습니까? [사용자 지정 서체 설정]
- 전체 애플리케이션과 모든 구성 요소가 기본 서체가 아닌 사용자 지정 서체를 사용해야 한다는 것을 한 곳에서 코드로 수행할 수 있는 방법이 있습니까?
네 가능합니다.
텍스트 보기를 확장하는 사용자 정의 보기를 작성해야 합니다.
attrs.xml
인에values
폴더:
<resources>
<declare-styleable name="MyTextView">
<attr name="first_name" format="string"/>
<attr name="last_name" format="string"/>
<attr name="ttf_name" format="string"/>
</declare-styleable>
</resources>
main.xml
:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:lht="http://schemas.android.com/apk/res/com.lht"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello"/>
<com.lht.ui.MyTextView
android:id="@+id/MyTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello friends"
lht:ttf_name="ITCBLKAD.TTF"
/>
</LinearLayout>
MyTextView.java
:
package com.lht.ui;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;
public class MyTextView extends TextView {
Context context;
String ttfName;
String TAG = getClass().getName();
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
for (int i = 0; i < attrs.getAttributeCount(); i++) {
Log.i(TAG, attrs.getAttributeName(i));
/*
* Read value of custom attributes
*/
this.ttfName = attrs.getAttributeValue(
"http://schemas.android.com/apk/res/com.lht", "ttf_name");
Log.i(TAG, "firstText " + firstText);
// Log.i(TAG, "lastText "+ lastText);
init();
}
}
private void init() {
Typeface font = Typeface.createFromAsset(context.getAssets(), ttfName);
setTypeface(font);
}
@Override
public void setTypeface(Typeface tf) {
// TODO Auto-generated method stub
super.setTypeface(tf);
}
}
XML에서 이것을 할 수 있는 방법이 있습니까?
아니요, 미안해요.XML을 통해서만 내장 서체를 지정할 수 있습니다.
전체 애플리케이션과 모든 구성 요소가 기본 서체가 아닌 사용자 지정 서체를 사용해야 한다는 것을 한 곳에서 코드로 수행할 수 있는 방법이 있습니까?
내가 알고 있는 것은 아닙니다.
요즘에는 다음과 같은 다양한 옵션이 있습니다.
SDK 의()를Android 및
appcompat
사용하지 않는 사용자를 위한 타사 라이브러리
appcompat
,
레이아웃 xml이나 Activities를 변경할 필요가 없는 보다 "잔인한 힘"의 방식으로 이 작업을 수행했습니다.
Android 버전 2.1에서 4.4까지 테스트되었습니다.응용 프로그램 클래스에서 앱 시작 시 실행:
private void setDefaultFont() {
try {
final Typeface bold = Typeface.createFromAsset(getAssets(), DEFAULT_BOLD_FONT_FILENAME);
final Typeface italic = Typeface.createFromAsset(getAssets(), DEFAULT_ITALIC_FONT_FILENAME);
final Typeface boldItalic = Typeface.createFromAsset(getAssets(), DEFAULT_BOLD_ITALIC_FONT_FILENAME);
final Typeface regular = Typeface.createFromAsset(getAssets(),DEFAULT_NORMAL_FONT_FILENAME);
Field DEFAULT = Typeface.class.getDeclaredField("DEFAULT");
DEFAULT.setAccessible(true);
DEFAULT.set(null, regular);
Field DEFAULT_BOLD = Typeface.class.getDeclaredField("DEFAULT_BOLD");
DEFAULT_BOLD.setAccessible(true);
DEFAULT_BOLD.set(null, bold);
Field sDefaults = Typeface.class.getDeclaredField("sDefaults");
sDefaults.setAccessible(true);
sDefaults.set(null, new Typeface[]{
regular, bold, italic, boldItalic
});
} catch (NoSuchFieldException e) {
logFontError(e);
} catch (IllegalAccessException e) {
logFontError(e);
} catch (Throwable e) {
//cannot crash app if there is a failure with overriding the default font!
logFontError(e);
}
}
보다 완벽한 예는 http://github.com/perchrh/FontOverrideExample 을 참조하십시오.
Manish의 답변을 가장 빠르고 목표로 하는 방법으로 지지하고 있지만, 보기 계층 구조를 통해 재귀적으로 반복하고 모든 요소의 서체를 차례로 업데이트하는 순진한 솔루션도 보았습니다.이와 같은 것:
public static void applyFonts(final View v, Typeface fontToSet)
{
try {
if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++) {
View child = vg.getChildAt(i);
applyFonts(child, fontToSet);
}
} else if (v instanceof TextView) {
((TextView)v).setTypeface(fontToSet);
}
} catch (Exception e) {
e.printStackTrace();
// ignore
}
}
에서 에서 이 .onContentChanged()
방법들.
이를 중앙 집중식으로 수행할 수 있었습니다. 그 결과는 다음과 같습니다.
과 같은 가 .Activity
사용자 지정 글꼴이 필요한 경우 확장합니다.
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater.Factory;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
public class CustomFontActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
getLayoutInflater().setFactory(new Factory() {
@Override
public View onCreateView(String name, Context context,
AttributeSet attrs) {
View v = tryInflate(name, context, attrs);
if (v instanceof TextView) {
setTypeFace((TextView) v);
}
return v;
}
});
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private View tryInflate(String name, Context context, AttributeSet attrs) {
LayoutInflater li = LayoutInflater.from(context);
View v = null;
try {
v = li.createView(name, null, attrs);
} catch (Exception e) {
try {
v = li.createView("android.widget." + name, null, attrs);
} catch (Exception e1) {
}
}
return v;
}
private void setTypeFace(TextView tv) {
tv.setTypeface(FontUtils.getFonts(this, "MTCORSVA.TTF"));
}
}
하지만 지원 패키지의 활동을 사용하는 경우에는 예를 예로 들 수 있습니다.FragmentActivity
그럼 이걸 사용합니다.Activity
:
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
public class CustomFontFragmentActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// we can't setLayout Factory as its already set by FragmentActivity so we
// use this approach
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
View v = super.onCreateView(name, context, attrs);
if (v == null) {
v = tryInflate(name, context, attrs);
if (v instanceof TextView) {
setTypeFace((TextView) v);
}
}
return v;
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public View onCreateView(View parent, String name, Context context,
AttributeSet attrs) {
View v = super.onCreateView(parent, name, context, attrs);
if (v == null) {
v = tryInflate(name, context, attrs);
if (v instanceof TextView) {
setTypeFace((TextView) v);
}
}
return v;
}
private View tryInflate(String name, Context context, AttributeSet attrs) {
LayoutInflater li = LayoutInflater.from(context);
View v = null;
try {
v = li.createView(name, null, attrs);
} catch (Exception e) {
try {
v = li.createView("android.widget." + name, null, attrs);
} catch (Exception e1) {
}
}
return v;
}
private void setTypeFace(TextView tv) {
tv.setTypeface(FontUtils.getFonts(this, "MTCORSVA.TTF"));
}
}
로 이 코드를 본 적이 .Fragment
아직, 하지만 잘 되기를 바랍니다.
나의FontUtils
간단하기 때문에 여기 https://code.google.com/p/android/issues/detail?id=9904 에서 언급된 ICS 이전 문제도 해결할 수 있습니다.
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.graphics.Typeface;
public class FontUtils {
private static Map<String, Typeface> TYPEFACE = new HashMap<String, Typeface>();
public static Typeface getFonts(Context context, String name) {
Typeface typeface = TYPEFACE.get(name);
if (typeface == null) {
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/"
+ name);
TYPEFACE.put(name, typeface);
}
return typeface;
}
}
안녕하세요 저는 또한 다른 와이드지를 위해 제 앱에 2개의 다른 폰트가 필요합니다!이 방법을 사용합니다.
응용프로그램 클래스에서 정적 메서드를 만듭니다.
public static Typeface getTypeface(Context context, String typeface) {
if (mFont == null) {
mFont = Typeface.createFromAsset(context.getAssets(), typeface);
}
return mFont;
}
문자열 서체는 자산 폴더의 xyz.ttf를 나타냅니다.(Constants Class를 만들었습니다) 이제 앱의 모든 곳에서 이를 사용할 수 있습니다.
mTextView = (TextView) findViewById(R.id.text_view);
mTextView.setTypeface(MyApplication.getTypeface(this, Constants.TYPEFACE_XY));
유일한 문제는 글꼴을 사용하려는 모든 위젯에 필요하다는 것입니다!하지만 저는 이게 최선의 방법이라고 생각합니다.
저는 pospi의 제안과 Richard가 했던 것처럼 'tag' 속성을 이용하여 커스텀 폰트를 로드하고 그들의 태그에 따라 뷰에 적용하는 커스텀 클래스를 만들었습니다.
기본적으로 속성 Android:fontFamily에서 TypeFace를 설정하는 대신 Android:tag Attritube를 사용하여 정의된 enum 중 하나로 설정합니다.
public class Fonts {
private AssetManager mngr;
public Fonts(Context context) {
mngr = context.getAssets();
}
private enum AssetTypefaces {
RobotoLight,
RobotoThin,
RobotoCondensedBold,
RobotoCondensedLight,
RobotoCondensedRegular
}
private Typeface getTypeface(AssetTypefaces font) {
Typeface tf = null;
switch (font) {
case RobotoLight:
tf = Typeface.createFromAsset(mngr,"fonts/Roboto-Light.ttf");
break;
case RobotoThin:
tf = Typeface.createFromAsset(mngr,"fonts/Roboto-Thin.ttf");
break;
case RobotoCondensedBold:
tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Bold.ttf");
break;
case RobotoCondensedLight:
tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Light.ttf");
break;
case RobotoCondensedRegular:
tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Regular.ttf");
break;
default:
tf = Typeface.DEFAULT;
break;
}
return tf;
}
public void setupLayoutTypefaces(View v) {
try {
if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++) {
View child = vg.getChildAt(i);
setupLayoutTypefaces(child);
}
} else if (v instanceof TextView) {
if (v.getTag().toString().equals(AssetTypefaces.RobotoLight.toString())){
((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoLight));
}else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedRegular.toString())) {
((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedRegular));
}else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedBold.toString())) {
((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedBold));
}else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedLight.toString())) {
((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedLight));
}else if (v.getTag().toString().equals(AssetTypefaces.RobotoThin.toString())) {
((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoThin));
}
}
} catch (Exception e) {
e.printStackTrace();
// ignore
}
}
}
활동 또는 조각에서 호출만 하면 됩니다.
Fonts fonts = new Fonts(getActivity());
fonts.setupLayoutTypefaces(mainLayout);
리사 레이의 블로그에서 좋은 해결책을 찾았습니다.새 데이터 바인딩을 사용하면 XML 파일의 글꼴을 설정할 수 있습니다.
@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"/>
좀 더 쉽게 할 수 있는 방법이 있을 것 같습니다.다음 클래스는 응용프로그램의 모든 구성요소에 대해 사용자 정의 서체를 설정합니다(클래스당 설정).
/**
* Base Activity of our app hierarchy.
* @author SNI
*/
public class BaseActivity extends Activity {
private static final String FONT_LOG_CAT_TAG = "FONT";
private static final boolean ENABLE_FONT_LOGGING = false;
private Typeface helloTypeface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
helloTypeface = Typeface.createFromAsset(getAssets(), "fonts/<your type face in assets/fonts folder>.ttf");
}
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
View view = super.onCreateView(name, context, attrs);
return setCustomTypeFaceIfNeeded(name, attrs, view);
}
@Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
View view = super.onCreateView(parent, name, context, attrs);
return setCustomTypeFaceIfNeeded(name, attrs, view);
}
protected View setCustomTypeFaceIfNeeded(String name, AttributeSet attrs, View view) {
View result = null;
if ("TextView".equals(name)) {
result = new TextView(this, attrs);
((TextView) result).setTypeface(helloTypeface);
}
if ("EditText".equals(name)) {
result = new EditText(this, attrs);
((EditText) result).setTypeface(helloTypeface);
}
if ("Button".equals(name)) {
result = new Button(this, attrs);
((Button) result).setTypeface(helloTypeface);
}
if (result == null) {
return view;
} else {
if (ENABLE_FONT_LOGGING) {
Log.v(FONT_LOG_CAT_TAG, "A type face was set on " + result.getId());
}
return result;
}
}
}
LayoutInflater의 기본 구현에서는 xml에서 글꼴 글꼴을 지정할 수 없습니다.그러나 저는 xml 태그에서 그러한 속성을 파싱할 LayoutInflater에 대한 커스텀 팩토리를 제공함으로써 xml에서 수행되는 것을 보았습니다.
기본적인 구조는 이렇게 할 겁니다.
public class TypefaceInflaterFactory implements LayoutInflater.Factory {
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
// CUSTOM CODE TO CREATE VIEW WITH TYPEFACE HERE
// RETURNING NULL HERE WILL TELL THE INFLATER TO USE THE
// DEFAULT MECHANISMS FOR INFLATING THE VIEW FROM THE XML
}
}
public class BaseActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater.from(this).setFactory(new TypefaceInflaterFactory());
}
}
이 문서에서는 이러한 메커니즘과 작성자가 이러한 방식으로 서체에 대한 xml 레이아웃 지원을 어떻게 제공하려고 하는지에 대한 자세한 설명을 제공합니다.저자의 구현 코드는 여기에서 확인할 수 있습니다.
일반 ProgressDialog/AlertDialog: 사용자 정의 글꼴을 일반 ProgressDialog/AlertDialog:
font=Typeface.createFromAsset(getAssets(),"DroidSans.ttf");
ProgressDialog dialog = ProgressDialog.show(this, "titleText", "messageText", true);
((TextView)dialog.findViewById(Resources.getSystem().getIdentifier("message", "id", "android"))).setTypeface(font);
((TextView)dialog.findViewById(Resources.getSystem().getIdentifier("alertTitle", "id", "android"))).setTypeface(font);
예, 기본 서체를 재정의하여 가능합니다.저는 이 솔루션을 따랐고, 한 번의 변경으로 모든 텍스트 뷰와 ActionBar 텍스트에도 매력적으로 작용했습니다.
public class MyApp extends Application {
@Override
public void onCreate() {
TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/Roboto-Regular.ttf"); // font from assets: "assets/fonts/Roboto-Regular.ttf
}
}
styles.xml
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/pantone</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>
<item name="android:windowDisablePreview">true</item>
<item name="android:typeface">serif</item>
</style>
위 링크에서 언급한 memes.xml 대신, 저는 저의 기본 앱 테마 태그에서 styles.xml에서 재정의할 기본 글꼴을 언급했습니다.덮어쓸 수 있는 기본 서체는 serif, sans, monospace 및 normal입니다.
글꼴 Util.java
public class TypefaceUtil {
/**
* Using reflection to override default typeface
* NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN
* @param context to work with assets
* @param defaultFontNameToOverride for example "monospace"
* @param customFontFileNameInAssets file name of the font from assets
*/
public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) {
try {
final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets);
final Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
defaultFontTypefaceField.setAccessible(true);
defaultFontTypefaceField.set(null, customFontTypeface);
} catch (Exception e) {
Log.e("Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
}
}
}
처음에는 덮어쓸 서체가 고정되어 있고 정의된 값이 설정되어 있다는 것을 몰랐지만, 결국 안드로이드가 글꼴과 서체를 어떻게 다루는지, 그리고 기본값을 어떻게 다루는지 이해하는 데 도움이 되었고, 이는 물론 다른 점입니다.
저는 이를 위해 (코틀린과 함께) DataBinding을 사용합니다.
바인딩 어댑터 설정:
BindingAdapter.kt
import android.graphics.Typeface
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.databinding.BindingAdapter
import java.util.*
object BindingAdapters {
@JvmStatic
@BindingAdapter("typeface", "typefaceStyle")
fun setTypeface(v: TextView, tf: Typeface?, style: Int?) {
v.setTypeface(tf ?: Typeface.DEFAULT, style ?: Typeface.NORMAL)
}
}
용도:
fragment_custom_view.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.graphics.Typeface" />
<variable
name="typeface"
type="android.graphics.Typeface" />
</data>
<TextView
android:id="@+id/reference"
style="@style/TextAppearance.MaterialComponents.Body1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="I'm formatted text"
app:typeface="@{typeface}"
app:typefaceStyle="@{Typeface.ITALIC}" />
</layout>
My Fragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentCustomView.bind(view)
binding.typeface = // some code to get user selected typeface
}
이제 사용자가 새 서체를 선택하면 바인딩 값과 설정한 모든 텍스트 보기를 업데이트할 수 있습니다.app:typeface
업데이트 될 것입니다.
앱 전체가 바뀌는지는 모르겠지만, 다른 방법으로는 바꿀 수 없는 일부 구성 요소를 변경할 수 있었습니다.
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);
pospi의 제안이 마음에 듭니다.XML에서 할 수 없는 추가 스타일링을 지정하기 위해 뷰의 '태그' 속성(XML - 'android:tag'에서 지정 가능)을 사용하는 것은 어떨까요. 저는 JSON을 좋아하기 때문에 키/값 집합을 지정하기 위해 JSON 문자열을 사용합니다.이 수업은 효과가 있습니다. 전화만 하면 됩니다.Style.setContentView(this, [resource id])
당신의 활동중에
public class Style {
/**
* Style a single view.
*/
public static void apply(View v) {
if (v.getTag() != null) {
try {
JSONObject json = new JSONObject((String)v.getTag());
if (json.has("typeface") && v instanceof TextView) {
((TextView)v).setTypeface(Typeface.createFromAsset(v.getContext().getAssets(),
json.getString("typeface")));
}
}
catch (JSONException e) {
// Some views have a tag without it being explicitly set!
}
}
}
/**
* Style the passed view hierarchy.
*/
public static View applyTree(View v) {
apply(v);
if (v instanceof ViewGroup) {
ViewGroup g = (ViewGroup)v;
for (int i = 0; i < g.getChildCount(); i++) {
applyTree(g.getChildAt(i));
}
}
return v;
}
/**
* Inflate, style, and set the content view for the passed activity.
*/
public static void setContentView(Activity activity, int resource) {
activity.setContentView(applyTree(activity.getLayoutInflater().inflate(resource, null)));
}
}
분명히 JSON을 사용하는 것을 가치 있게 만들기 위해 서체 이상의 것을 다루고 싶을 것입니다.
'태그' 속성의 장점은 테마로 사용하는 기본 스타일에 설정하여 모든 보기에 자동으로 적용할 수 있다는 것입니다.편집: 이렇게 하면 Android 4.0.3에서 인플레이션이 발생하는 동안 충돌이 발생합니다.스타일을 사용하여 텍스트 보기에 개별적으로 적용할 수도 있습니다.
코드에서 한 가지를 보게 될 것입니다. 일부 보기에는 태그가 명시적으로 설정되지 않은 태그가 있습니다. 이상하게도 그것은 'α ποκοπή'라는 문자열입니다. 구글 번역에 따르면, 그리스어로 '컷'되어 있다고 합니다.대체...?
@majinboo의 답변은 성능과 메모리 관리를 위해 수정되었습니다.둘 이상의 글꼴 필요 관련 활동은 생성자 자체를 매개변수로 지정하여 이 글꼴 클래스를 사용할 수 있습니다.
@Override
public void onCreate(Bundle savedInstanceState)
{
Font font = new Font(this);
}
수정된 글꼴 클래스는 다음과 같습니다.
public class Fonts
{
private HashMap<AssetTypefaces, Typeface> hashMapFonts;
private enum AssetTypefaces
{
RobotoLight,
RobotoThin,
RobotoCondensedBold,
RobotoCondensedLight,
RobotoCondensedRegular
}
public Fonts(Context context)
{
AssetManager mngr = context.getAssets();
hashMapFonts = new HashMap<AssetTypefaces, Typeface>();
hashMapFonts.put(AssetTypefaces.RobotoLight, Typeface.createFromAsset(mngr, "fonts/Roboto-Light.ttf"));
hashMapFonts.put(AssetTypefaces.RobotoThin, Typeface.createFromAsset(mngr, "fonts/Roboto-Thin.ttf"));
hashMapFonts.put(AssetTypefaces.RobotoCondensedBold, Typeface.createFromAsset(mngr, "fonts/RobotoCondensed-Bold.ttf"));
hashMapFonts.put(AssetTypefaces.RobotoCondensedLight, Typeface.createFromAsset(mngr, "fonts/RobotoCondensed-Light.ttf"));
hashMapFonts.put(AssetTypefaces.RobotoCondensedRegular, Typeface.createFromAsset(mngr, "fonts/RobotoCondensed-Regular.ttf"));
}
private Typeface getTypeface(String fontName)
{
try
{
AssetTypefaces typeface = AssetTypefaces.valueOf(fontName);
return hashMapFonts.get(typeface);
}
catch (IllegalArgumentException e)
{
// e.printStackTrace();
return Typeface.DEFAULT;
}
}
public void setupLayoutTypefaces(View v)
{
try
{
if (v instanceof ViewGroup)
{
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++)
{
View child = vg.getChildAt(i);
setupLayoutTypefaces(child);
}
}
else if (v instanceof TextView)
{
((TextView) v).setTypeface(getTypeface(v.getTag().toString()));
}
}
catch (Exception e)
{
e.printStackTrace();
// ignore
}
}
}
Xamarin에서 일하고 있습니다.안드로이드:
클래스:
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>
안드로이드 O로 맞춤 글꼴 사용이 쉬워진 것 같은데, 기본적으로 xml을 사용하면 됩니다.참고용으로 Android 공식 문서 링크를 첨부하였으며, 이를 통해 여전히 이 솔루션이 필요한 사람들에게 도움이 되기를 바랍니다.Android에서 사용자 지정 글꼴 작업
Android 8.0(API 레벨 26)부터 XML에서 사용자 정의 글꼴을 사용할 수 있음을 알면 유용할 수 있습니다.
간단히 말하면 다음과 같은 방법으로 할 수 있습니다.
.
res/font
.위젯 속성에 사용할 수 있습니다.
<Button android:fontFamily="@font/myfont"/>
, 에 res/values/styles.xml
<style name="MyButton" parent="android:Widget.Button">
<item name="android:fontFamily">@font/myfont</item>
</style>
스타일로 활용할 수 있습니다.
<Button style="@style/MyButton"/>
xml 파일에서 "fontPath" 속성을 직접 사용합니다.
style.xml에 사용하기 위해
<상품명="fontPath">fonts/프록시마노바 세미볼드.ttf</item>
직접 레이아웃 파일에 사용하기 위해
fontPath="fonts/ProximaNovaBold.ttf"
(참고 : 접두사에서 app/android 속성을 사용할 필요 없음)
절대 가능합니다.여러 가지 방법이 있습니다.가장 빠른 방법, Try-catch 방법으로 조건 만들기..특정 글꼴 스타일 조건을 사용해 보고 오류를 잡고 다른 글꼴 스타일을 정의합니다.
언급URL : https://stackoverflow.com/questions/2973270/using-a-custom-typeface-in-android
'programing' 카테고리의 다른 글
Safari에서 작동하지 않는 Sticky footer (0) | 2023.10.08 |
---|---|
C - 계산 시간을 알 수 있습니까? (0) | 2023.10.08 |
HTML5 캔버스 뷰포트의 너비 100% 높이? (0) | 2023.10.08 |
Laravel Expulent: 필드 ID로 배열 키 반환 (0) | 2023.10.08 |
Spring Framework의 JdbcTemplate 클래스를 사용하여 INSERT 문을 실행하는 방법 (0) | 2023.10.08 |