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.