TextView에서 글꼴을 변경하는 방법은 무엇입니까?


289

에서 글꼴을 변경하는 방법 TextView은 기본적으로 Arial로 표시됩니까? 로 바꾸는 방법 Helvetica?


1
나는 이것이 반복되는 질문이라고 생각합니다. 답변을 보려면 여기를 찾으십시오. stackoverflow.com/questions/2878882/android-develop-lcd-font/…
— the100rabh

당신이 내 링크 도움이 될 수 있습니다 stackoverflow.com/questions/2376250/...
— duggu

답변:


342

첫째, 기본값은 Arial이 아닙니다. 기본값은 Droid Sans입니다.

둘째, 다른 내장 글꼴로 변경하려면 android:typeface레이아웃 XML 또는 setTypeface()Java에서 사용하십시오.

셋째, Android에는 Helvetica 글꼴이 없습니다. 기본 제공 옵션은 Droid Sans ( sans), Droid Sans Mono ( monospace) 및 Droid Serif ( serif)입니다. 자신의 글꼴을 응용 프로그램과 함께 번들로 제공하고을 통해 사용할 수는 있지만 setTypeface()글꼴 파일은 크기가 크며 경우에 따라 라이센스 계약 (예 : Helvetica, Linotype 글꼴 )이 필요합니다.

편집하다

Android 디자인 언어는 스케일, 공간, 리듬 및 기본 그리드와의 정렬과 같은 기존의 타이포그래피 도구를 사용합니다. 사용자가 정보 화면을 빠르게 이해하려면 이러한 도구를 성공적으로 배포해야합니다. 이러한 타이포그래피 사용을 지원하기 위해 Ice Cream Sandwich는 UI 및 고해상도 화면의 요구 사항을 위해 특별히 개발 된 Roboto라는 새로운 유형의 제품군을 출시했습니다.

현재 TextView 프레임 워크는 각 무게에 대한 이탤릭 스타일과 함께 얇고 가벼우 며 규칙적이며 대담한 무게로 Roboto를 제공합니다. 또한이 프레임 워크는 각 무게에 대한 이탤릭체 스타일과 함께 Roboto Condensed 변형을 규칙적이고 대담한 무게로 제공합니다.

ICS 후, 안드로이드는 Roboto로 글꼴 스타일, 더 읽기 포함 Roboto로를

편집 2

Support Library 26의 출현으로 Android는 기본적으로 사용자 정의 글꼴을 지원합니다. XML / 프로그래밍 방식으로 개별적으로 TextViews로 설정할 수있는 res / fonts에 새 글꼴을 삽입 할 수 있습니다. 전체 애플리케이션의 기본 글꼴은 styles.xml을 정의하여 변경할 수도 있습니다. 안드로이드 개발자 문서에는 여기 에 대한 명확한 안내서가 있습니다.


6
XML에서 글꼴을 설정하는 방법이 없습니까? 왜?
— Jonny

5
@Jonny 당신은 실제로 할 수 있습니다. TextView를 확장하고 생성자에서 setTypeface를 호출하는 클래스를 만들고 있습니다.
— Mark Phillip

XML 레이아웃에서 어떻게해야합니까?
— M. Usman Khan

2
@ usman : 서예와 같은 타사 라이브러리가 필요합니다 : github.com/chrisjenx/Calligraphy
— CommonsWare

여러 줄로 인해 Java 코드를 사용하여 서체를 설정하는 것이 어렵습니다. 사용자 정의 글꼴을 설정하는 라이브러리를 만들었습니다. 이 답변에서 라이브러리 사용법을 찾을 수 있습니다. stackoverflow.com/a/42001474/4446392
— Chathura Jayanath

254

먼저 .ttf필요한 글꼴 파일 ( arial.ttf)을 다운로드하십시오 . assets 폴더에 넣으십시오 . (자산 폴더 안에 fonts 라는 새 폴더를 만들어 그 안에 넣습니다.) 다음 코드를 사용하여 글꼴을 다음에 적용하십시오 TextView.

Typeface type = Typeface.createFromAsset(getAssets(),"fonts/arial.ttf"); 
textView.setTypeface(type);

Mayur에게, .ttf 파일을 어디서 구할 수 있습니까?
— lonelearner

3
친애하는 @lonelearner 당신은 1001freefonts.com에서 무료 글꼴 (.ttf) 파일을 다운로드 하거나 그냥 구글 "무료 글꼴"
— ymerdrengene

10
Android Studio를 사용하고 "자산"폴더를 찾을 수없는 경우이 질문을 참조하십시오 . 짧은 대답 : src/main/assets/fonts/.
— adamdport

51
Typeface tf = Typeface.createFromAsset(getAssets(),
        "fonts/DroidSansFallback.ttf");
TextView tv = (TextView) findViewById(R.id.CustomFontText);
tv.setTypeface(tf);

33

모든 글꼴을 포함하는 정적 클래스 를 만들 수 있습니다 . 이렇게하면 성능에 크게 영향을 줄 수있는 글꼴을 여러 번 만들지 않습니다 . " asset "폴더 아래에 " fonts " 라는 하위 폴더 를 작성하십시오 .

다음과 같은 작업을 수행하십시오.

public class CustomFontsLoader {

public static final int FONT_NAME_1 =   0;
public static final int FONT_NAME_2 =   1;
public static final int FONT_NAME_3 =   2;

private static final int NUM_OF_CUSTOM_FONTS = 3;

private static boolean fontsLoaded = false;

private static Typeface[] fonts = new Typeface[3];

private static String[] fontPath = {
    "fonts/FONT_NAME_1.ttf",
    "fonts/FONT_NAME_2.ttf",
    "fonts/FONT_NAME_3.ttf"
};


/**
 * Returns a loaded custom font based on it's identifier. 
 * 
 * @param context - the current context
 * @param fontIdentifier = the identifier of the requested font
 * 
 * @return Typeface object of the requested font.
 */
public static Typeface getTypeface(Context context, int fontIdentifier) {
    if (!fontsLoaded) {
        loadFonts(context);
    }
    return fonts[fontIdentifier];
}


private static void loadFonts(Context context) {
    for (int i = 0; i < NUM_OF_CUSTOM_FONTS; i++) {
        fonts[i] = Typeface.createFromAsset(context.getAssets(), fontPath[i]);
    }
    fontsLoaded = true;

}
}

이런 식으로 응용 프로그램의 어느 곳에서나 글꼴을 얻을 수 있습니다.


1
멋진 친구! 이것이 OOP의 아름다움입니다. 훌륭한 일! :)
— Joshua Michael Wagoner

이 수업은 어떻게 사용합니까?
— Jack

이 코드를 프로젝트에 배치하고 글꼴에 맞게 조정 한 다음 앱 어디에서나 getTypeface (..) 정적 메서드를 사용해야합니다.
— Daniel L.

비슷한 솔루션을 사용했지만 성능 향상을 위해 캐싱을 추가했습니다. ... 어쨌든 일부 전화에서는 글꼴이 작동하고 다른 전화에서는 작동하지 않는 상황이 발생 했습니까?
— RJFares

20

모범 사례

TextViewPlus.java :

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 typeface = null;
        try {
            typeface = Typeface.createFromAsset(ctx.getAssets(), asset);
        } catch (Exception e) {
            Log.e(TAG, "Unable to load typeface: "+e.getMessage());
            return false;
        }

        setTypeface(typeface);
        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>

사용하는 방법:

<?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-auto"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.mypackage.TextViewPlus
        android:id="@+id/textViewPlus1"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:text="@string/showingOffTheNewTypeface"
        foo:customFont="my_font_name_regular.otf">
    </com.mypackage.TextViewPlus>
</LinearLayout>

이것이 도움이되기를 바랍니다.


1
TextView를 서브 클래 싱하는 것이 가장 좋은 이유는 무엇입니까?
— Stealth Rabbi

@Stealth Rabbi, 여기서는 xml로만 사용자 정의 글꼴을 전달할 수 있으며 각 textview에 대해 특별한 Java 코드를 작성할 필요가 없습니다.
— Hiren Patel

이를위한 라이브러리가 있습니다. 자산 폴더 아래에 글꼴을 추가하고 XML로 선언하면됩니다. github.com/febaisi/CustomTextView
— febaisi

라이브러리 외모 벌금,하지만 유일한 문제는 안드로이드 21+위한 것입니다
— loloof64


17

위의 답변은 정확합니다. 해당 코드를 사용하는 경우 "자산"폴더 아래에 "fonts"라는 하위 폴더를 작성하십시오.


1
귀하의 의견은 중복됩니다. 위의 설명은 당신이 말한 것을 정확하게 말해줍니다. 그리고
— Joshua Michael Wagoner

14

글꼴 작성을 통합하는 또 다른 방법은 ...

public class Font {
  public static final Font  PROXIMA_NOVA    = new Font("ProximaNovaRegular.otf");
  public static final Font  FRANKLIN_GOTHIC = new Font("FranklinGothicURWBoo.ttf");
  private final String      assetName;
  private volatile Typeface typeface;

  private Font(String assetName) {
    this.assetName = assetName;
  }

  public void apply(Context context, TextView textView) {
    if (typeface == null) {
      synchronized (this) {
        if (typeface == null) {
          typeface = Typeface.createFromAsset(context.getAssets(), assetName);
        }
      }
    }
    textView.setTypeface(typeface);
  }
}

그런 다음 활동에 사용하십시오 ...

myTextView = (TextView) findViewById(R.id.myTextView);
Font.PROXIMA_NOVA.apply(this, myTextView);

휘발성 필드가있는이 이중 점검 잠금 관용구는 Java 1.5 이상에서 사용 된 메모리 모델에서만 올바르게 작동합니다.


이 답변에 1 개의 투표 만 있고 위의 답변에 15 개의 답변이있는 이유는 무엇입니까? 다른 하나를 더 좋게 만드는 것은 무엇입니까? 이것은 싱글 톤 원리를 사용하는 것이 더 간단합니다 ...?
— Koen Demonie

방금 생성자가 공개되어 있음을 보았으므로 액세스 할 필요가 없으므로 비공개로 만들었습니다. 당신은 어쨌든 당신의 내부 Font vars를 사용하고 있습니다.
— Koen Demonie

물론 개인 생성자 여야합니다. 잘 발견 :) 편집합니다!
— Chris Aitchison

12

모범 사례는 Android 지원 라이브러리 버전 26.0.0 이상을 사용하는 것입니다.

1 단계 : 글꼴 파일 추가

  1. 에서 고해상도 새로 만들 폴더 글꼴 리소스 사전을
  2. 글꼴 파일 추가 ( .ttf , .orf )

예를 들어 글꼴 파일이 helvetica_neue.ttf 인 경우 R.font.helvetica_neue를 생성합니다.

2 단계 : 글꼴 모음 만들기

  1. 에서 글꼴 폴더에 새 리소스 파일을 추가
  2. 각 글꼴 파일, 스타일 및 가중치 속성을 요소에 포함하십시오.

예를 들면 다음과 같습니다.

<?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/helvetica_neue" />
</font-family>

3 단계 : 사용

xml 레이아웃에서 :

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="@font/my_font"/>

또는 스타일을 지정할 글꼴을 추가하십시오.

<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
    <item name="android:fontFamily">@font/lobster</item>
</style>

더 많은 예제를 보려면 문서를 따르십시오.

폰트로 작업하기


7

조금 낡았지만 CustomFontLoader 클래스를 조금 개선했으며 공유 할 수 있도록 공유하고 싶었습니다. 이 코드로 새 클래스를 만드십시오.

 import android.content.Context;
 import android.graphics.Typeface;

public enum FontLoader {

ARIAL("arial"),
TIMES("times"),
VERDANA("verdana"),
TREBUCHET("trbuchet"),
GEORGIA("georgia"),
GENEVA("geneva"),
SANS("sans"),
COURIER("courier"),
TAHOMA("tahoma"),
LUCIDA("lucida");   


private final String name;
private Typeface typeFace;


private FontLoader(final String name) {
    this.name = name;

    typeFace=null;  
}

public static Typeface getTypeFace(Context context,String name){
    try {
        FontLoader item=FontLoader.valueOf(name.toUpperCase(Locale.getDefault()));
        if(item.typeFace==null){                
            item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");                 
        }           
        return item.typeFace;
    } catch (Exception e) {         
        return null;
    }                   
}
public static Typeface getTypeFace(Context context,int id){
    FontLoader myArray[]= FontLoader.values();
    if(!(id<myArray.length)){           
        return null;
    } 
    try {
        if(myArray[id].typeFace==null){     
            myArray[id].typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+myArray[id].name+".ttf");                       
        }       
        return myArray[id].typeFace;    
    }catch (Exception e) {          
        return null;
    }   

}

public static Typeface getTypeFaceByName(Context context,String name){      
    for(FontLoader item: FontLoader.values()){              
        if(name.equalsIgnoreCase(item.name)){
            if(item.typeFace==null){
                try{
                    item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");     
                }catch (Exception e) {          
                    return null;
                }   
            }
            return item.typeFace;
        }               
    }
    return null;
}   

public static void loadAllFonts(Context context){       
    for(FontLoader item: FontLoader.values()){              
        if(item.typeFace==null){
            try{
                item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");     
            }catch (Exception e) {
                item.typeFace=null;
            }   
        }                
    }       
}   
}

그런 다음 textview 에서이 코드를 사용하십시오.

 Typeface typeFace=FontLoader.getTypeFace(context,"arial");  
 if(typeFace!=null) myTextView.setTypeface(typeFace);

5

나는 마침내 이것에 대한 매우 쉬운 해결책을 얻었다.

  1. 앱 레벨 gradle 에서이 지원 라이브러리를 사용 하십시오 .

    compile 'com.android.support:appcompat-v7:26.0.2'
    compile 'com.android.support:support-v4:26.0.2'
  2. 그런 다음 res 폴더 안에 "font" 라는 디렉토리를 만드십시오.

  3. 해당 글꼴 디렉토리에 fonts (ttf) 파일을 넣고 이름 지정 규칙을 명심하십시오 (예 : 특수 문자, 대문자 및 공백 또는 탭을 포함하지 않아야 함)
  4. 그런 다음 xml 에서 해당 글꼴을 다음 과 같이 참조 하십시오.

            <Button
            android:id="@+id/btn_choose_employee"
            android:layout_width="140dp"
            android:layout_height="40dp"
            android:layout_centerInParent="true"
            android:background="@drawable/rounded_red_btn"
            android:onClick="btnEmployeeClickedAction"
            android:text="@string/searching_jobs"
            android:textAllCaps="false"
            android:textColor="@color/white"
            android:fontFamily="@font/times_new_roman_test"
            />

이 예에서 times_new_roman_test 는 해당 글꼴 디렉토리의 글꼴 ttf 파일입니다.


4
import java.lang.ref.WeakReference;
import java.util.HashMap;

import android.content.Context;
import android.graphics.Typeface;

public class FontsManager {

    private static FontsManager instance;

    private static HashMap<String, WeakReference<Typeface>> typefaces = new HashMap<String, WeakReference<Typeface>>();

    private static Context context;

    private FontsManager(final Context ctx) {
        if (context == null) {
            context = ctx;
        }
    }

    public static FontsManager getInstance(final Context appContext) {
        if (instance == null) {
            instance = new FontsManager(appContext);
        }
        return instance;
    }

    public static FontsManager getInstance() {
        if (instance == null) {
            throw new RuntimeException(
                    "Call getInstance(Context context) at least once to init the singleton properly");
        }
        return instance;
    }

    public Typeface getFont(final String assetName) {
        final WeakReference<Typeface> tfReference = typefaces.get(assetName);
        if (tfReference == null || tfReference.get() == null) {
            final Typeface tf = Typeface.createFromAsset(context.getResources().getAssets(),
                    assetName);
            typefaces.put(assetName, new WeakReference<Typeface>(tf));
            return tf;
        }
        return tfReference.get();
    }

}

이런 식으로 TextView에서 상속하고 생성자에서 setTypeface를 호출하는 View를 만들 수 있습니다.


1
안녕하세요, 왜 WeakReference를 사용하여 TypeFace 객체를 보유하고 있습니까?
— 게으른

3

폰트가 내부에 저장 res/asset/fonts/Helvetica.ttf되면 다음을 사용하십시오.

Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/Helvetica.ttf"); 
txt.setTypeface(tf);

또는 글꼴 파일이 내부에 저장되어있는 res/font/helvetica.ttf경우 다음을 사용하십시오.

Typeface tf = ResourcesCompat.getFont(this,R.font.helvetica);
txt.setTypeface(tf);

2
고마워, res 폴더에있는 부분을 찾고있었습니다!
— Mikkel Larsen

2

자산에서 글꼴을 가져 와서 모든 자식으로 설정

public static void overrideFonts(final Context context, final View v) {
    try {
        if (v instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) v;
            for (int i = 0; i < vg.getChildCount(); i++) {
                View child = vg.getChildAt(i);
                overrideFonts(context, child);
         }
        } else if (v instanceof TextView ) {
            ((TextView) v).setTypeface(Typeface.createFromAsset(context.getAssets(),"DroidNaskh.ttf"));// "BKOODB.TTF"));
        }
    } catch (Exception e) {
 }
 } 

2
  1. FontTextView.java 클래스를 추가하십시오.


public class FontTextView extends TextView {
    String fonts[] = {"HelveticaNeue.ttf", "HelveticaNeueLight.ttf", "motschcc.ttf", "symbol.ttf"};

    public FontTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs);
    }

    public FontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (!isInEditMode()) {
            init(attrs);
        }

    }

    public FontTextView(Context context) {
        super(context);
        if (!isInEditMode()) {
            init(null);
        }
    }

    private void init(AttributeSet attrs) {
        if (attrs != null) {
            TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.FontTextView);
            if (a.getString(R.styleable.FontTextView_font_type) != null) {
                String fontName = fonts[Integer.valueOf(a.getString(R.styleable.FontTextView_font_type))];

                if (fontName != null) {
                    Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/" + fontName);
                    setTypeface(myTypeface);
                }
                a.recycle();
            }
        }
    }
}


  1. 자산 라이브러리 글꼴에 추가
    여기에 이미지 설명을 입력하십시오


  1. attrs.xml에 추가하십시오. 숫자는 배열 클래스 순서대로 있어야합니다.

    <declare-styleable name="FontTextView">
    <attr name="font_type" format="enum">
        <enum name="HelveticaNeue" value="0"/>
        <enum name="HelveticaNeueLight" value="1"/>
        <enum name="motschcc" value="2"/>
        <enum name="symbol" value="3"/>
    </attr>


  1. 목록에서 글꼴을 선택하십시오
    여기에 이미지 설명을 입력하십시오

MainActivity에서이 클래스를 인스턴스화해야합니까? 그것은 나를 위해 아무것도 바꾸지 않기 때문에.
— Tobias Mayr

1

Android는 Roboto 글꼴을 사용합니다. Roboto 글꼴은 고밀도 화면에서 멋지게 보이는 몇 가지 다른 가중치 (일반, 가벼움, 얇음, 압축)가있는 정말 멋진 글꼴입니다.

roboto 글꼴을 확인하려면 아래 링크를 확인하십시오.

XML 레이아웃에서 Roboto를 사용하는 방법

귀하의 질문으로 돌아가서 앱에서 모든 TextView / Button 의 글꼴을 변경 하려면 Roboto-light 글꼴 을 사용하도록 아래 코드를 styles.xml에 추가하십시오 .

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    ......
    <item name="android:buttonStyle">@style/MyButton</item>
    <item name="android:textViewStyle">@style/MyTextView</item>
</style>

<style name="MyButton" parent="@style/Widget.AppCompat.Button">
    <item name="android:textAllCaps">false</item>
    <item name="android:fontFamily">sans-serif-light</item>
</style>

<style name="MyTextView" parent="@style/TextAppearance.AppCompat">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

그리고 AndroidManifest.xml에서 'AppTheme'을 사용하는 것을 잊지 마십시오

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    ......
</application>

0

어쩌면 조금 더 간단한 것 :

public class Fonts {
  public static HashSet<String,Typeface> fonts = new HashSet<>();

  public static Typeface get(Context context, String file) {
    if (! fonts.contains(file)) {
      synchronized (this) {
        Typeface typeface = Typeface.createFromAsset(context.getAssets(), name);
        fonts.put(name, typeface);
      }
    }
    return fonts.get(file);
  }
}

// Usage
Typeface myFont = Fonts.get("arial.ttf");

(이 코드는 테스트되지 않았지만 일반적으로이 방법은 잘 작동합니다.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.