태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

티스토리 툴바



이 게시물을 무단으로 사용하는 행위(비영리, 영리 포함)는 CCL 2.0 저작자 표시-비영리-변경금지 라이센스에 의거하여 금지되어 있습니다. 원본 글의 출처 및 저작자를 표시해 주신다면 글의 스크랩은 자유롭게 하실 수 있습니다. 단, 비영리 목적의 발표(스터디 등)에 위 글을 사용하고 싶으신 분은 제게 미리 메일로 문의 부탁드립니다.

저작권과 관련된 자세한 사항은 이곳을 참조해 주시기 바랍니다.


[애플리케이션 정보]

액티비티


레이아웃


프로젝트 파일 :



TextView에 외부 폰트를 적용하려면 다음 절차를 거쳐야 합니다.

  1. /assets 폴더에 적용하려는 폰트 파일 넣어주기
  2. Typeface.createFromAsset(AssetManager, String); 을 사용하여 폰트 로드
  3. TextView.setTypeface(Typeface)를 사용하여  TextView에 폰트 적용

예제 애플리케이션에서는 두 가지 방법을 사용하여 폰트를 적용합니다. 하나는 TextView를 상속받아 새로운 TextView를 만들고, XML에 선언할 때 속성 지정을 통해 원하는 폰트를 로드할 수 있는 방법입니다. 다른 하나의 방법은 액티비티에서 setContentView()를 사용하여 레이아웃을 지정할 때, TextView의 인스턴스만 골라 Typeface를 지정하는 방법입니다.

먼저, TextView를 상속한 뷰를 만드는 방식부터 알아보겠습니다. XML을 통해 폰트를 지정할 수 있도록 하기 위해 attrs.xml을 생성하여 다음과 같이 구현합니다. typeface라는 속성으로 폰트 이름을 설정하도록 합니다.

[attrs.xml]

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="StyledTextView">
        <attr name="typeface" format="string"/>
    </declare-styleable>
</resources>

다음, TextView를 상속한 StyledTextView 클래스를 만듭니다.

[StyledTextView.java]

public class StyledTextView extends TextView {

	public StyledTextView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		applyTypeface(context, attrs);
	}

	public StyledTextView(Context context, AttributeSet attrs) {
		super(context, attrs);
		applyTypeface(context, attrs);
	}

	public StyledTextView(Context context) {
		super(context);
	}
	
	private void applyTypeface(Context context, AttributeSet attrs){
		TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.StyledTextView);
		String typefaceName = arr.getString(R.styleable.StyledTextView_typeface);
		Typeface typeface = null;
		try{
			typeface = Typeface.createFromAsset(context.getAssets(), typefaceName);
			setTypeface(typeface);
		}catch(Exception e){
			e.printStackTrace();
		}	
	}
}

이를 활용하여 구성한 XML레이아웃 소스의 일부는 다음과 같습니다. StyledTextView에 attribute를 지정하기 위해 xml namespace를 지정한 후, typeface속성에 폰트파일 이름을 입력합니다. 이 구현은 attribute를 통해 폰트를 지정하므로, 하나의 레이아웃 내에서 여러 폰트를 쓰기 용이합니다.

[texts_customized.xml]

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:androidhuman="http://schemas.android.com/apk/res/com.androidhuman.example.CustomFont"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.androidhuman.example.CustomFont.StyledTextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Lorem ipsum"
        androidhuman:typeface="NanumPen.otf"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <com.androidhuman.example.CustomFont.StyledTextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="dolor sit amet"
        androidhuman:typeface="NanumPen.otf"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <com.androidhuman.example.CustomFont.StyledTextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        androidhuman:typeface="NanumMyeongjo.otf"
        android:text="consectetu...

다음은 레이아웃에서는 일반 TextView를 사용하되, 액티비티에서  TextView의 인스턴스를 찾아 폰트를 적용하는 방식입니다. 이 경우 전체 TextView에 동일한 폰트가 적용됩니다. 다음은 이러한 방법을 적용한 StylizedFontActivity 액티비티입니다.

[StyledFontActivity.java]
public class StylizedFontActivity extends Activity {

	private static final String TYPEFACE_NAME = "NanumMyeongjo.otf";
	private Typeface typeface = null;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    loadTypeface();
	    setContentView(R.layout.texts);
	}
	
	private void loadTypeface(){
		if(typeface==null)
			typeface = Typeface.createFromAsset(getAssets(), TYPEFACE_NAME);
	}

	@Override
	public void setContentView(int viewId) {
		View view = LayoutInflater.from(this).inflate(viewId, null);
		ViewGroup group = (ViewGroup)view;
		int childCnt = group.getChildCount();
		for(int i=0; i<childCnt; i++){
			View v = group.getChildAt(i);
			if(v instanceof TextView){
				((TextView)v).setTypeface(typeface);
			}
		}
		super.setContentView(view);
	}

}

이 구현에서는 액티비티가 로드될 때 딱 한번만 폰트를 로드하므로, 별도의 TextView클래스를 만들어 쓰는 경우보다 부하가 매우 적습니다. 여기에서는 액티비티에 적용하여 setContentView()를 오버라이드 하였지만, 프래그먼트라면 onCreateView()를 오버라이드하면 동일하게 구현이 가능해 보입니다.

위의 두 방식을 적용하여 실행한 결과입니다. 왼쪽 그림이 첫번째 방법, 오른쪽 그림이 두번째 방법을 적용한 결과입니다.


두 방법의 실행 시간을 대략적으로 측정해 보았습니다. 테스트 환경은 다음과 같습니다.

  • Macbook Pro 15-inch, 2.2GHz Intel Core i7, 4GB 1333MHZ DDR3
  • emulator (API level 14/Google APIs, HVGA)

 방법  소요시간
 StyledTextView  약 4.3초
 onCreate() 오버라이드  약 1.22초

갤럭시S에서 테스트했을 때와 유사한 결과가 나왔습니다. 혹시 궁금해서 갤럭시 노트에서 다시 테스트를 수행해 보았습니다.

 방법  소요시간
 StyledTextView  약 0.8초
 onCreate() 오버라이드  거의 지연 없음

사양의 차이인건진 몰라도, 생각보다 딜레이가 거의 없어서 좀 놀랐습니다. 하지만, 저사양 단말기에서 이를 실행한다면 첫 번째 방법의 경우 실제로 이를 사용하기엔 문제가 좀 있지 않을까 싶습니다.

저작자 표시 비영리 변경 금지
크리에이티브 커먼즈 라이선스
Creative Commons License


안드로이드 정보, 강좌를 누구보다 빨리 접하고 싶으신가요?

그렇다면 이메일 구독 혹은  구글 리더에 피드 추가 를 통해 업데이트되는 최신 글들을 받아보실 수 있습니다. :)




TRACKBACK http://androidhuman.tistory.com/trackback/497 관련글 쓰기

댓글을 달아 주세요

  1. 안드러이드

    폰트사이즈는 어케지정하나요??

    2012/02/24 20:38 [ ADDR : EDIT/ DEL : REPLY ]
    • 폰트 크기는 android:textSize 속성을 사용하여 조정 가능합니다.

      위의 예제 코드에서는 시스템에서 지정한 스타일을 사용(andoid:attr/textAppearaceMedium 등)을 사용했지만, 이 또한 내부를 살펴보면 textSize가 미리 설정되어 있고, 이를 TextView의 속성에 적용하는 것입니다.

      2012/02/24 21:58 [ ADDR : EDIT/ DEL ]
  2. 앰뽕

    강좌 정말 잘 보았습니다. 한가지 질문이 있어서 댓글을 남깁니다.
    결론부분을 보면 두번째 방법을 더 권장하고 퍼포먼스가 잘 나오는데요.
    여러개의 뷰에 두번째 방법으로 공통으로 적용을 하려고 유틸리티 클래스를 만들려고 했는데
    어떤 방식으로 구현을 해야 할지 모르겠어서 이렇게 질문 드립니다.
    특정 유틸리티 클래스의 함수 한번호출로 저 텍스트뷰 스타일을 적용하려면 어떻게 해야 할까요?
    좋은 강좌 감사합니다.

    2012/03/05 18:58 [ ADDR : EDIT/ DEL : REPLY ]
    • 두번째 방법은 TextView의 인스턴스들을 찾고 이에만 Typeface를 적용하는 방식입니다. 이 부분만 뽑아낸다면 가능하지 않을까 싶네요. :)

      2012/03/10 20:50 [ ADDR : EDIT/ DEL ]
  3. 텍스트의 중앙정렬 어떻게할까요... 쩝...

    2012/08/19 20:25 [ ADDR : EDIT/ DEL : REPLY ]
    • <TextView android:gravity="center_horizontal"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      ...>

      텍스트 너비가 컨테이너 폭을 모두 사용하고 있다면 위의 코드를 쓰면 되고, 만약 그렇지 않다면 LinearLayout 컨테이너에 있을 경우 android:layout_gravity="center_horizontal"을 넣어주면 됩니다.

      2012/08/20 04:00 [ ADDR : EDIT/ DEL ]
  4. 접섭

    오! 나도 얼마전에 이와 비슷한 경험을 했어. 첫 번째 방법으로 CustomTextView에서 Font를 적용 assets에서 가져와서 적용하다보니 성능에 엄청난 문제가 생겨서 두 번째 방법으로 다시 적용했는데, 가끔 동적생성하는 View 에 대해서 적용이 곤란하더라; 그래서 해결방법이 extends application 클래스를 하나 만들어서, 그 쪽에서 static 으로 Typeface 인스턴스를 만들고 get 메소드를 만들어서 CustomTextView 클래스에서 그거 가져다 쓰는 방법을 썼더니 괜찮더라! 커니 요즘 잘 지내나?

    2012/08/21 10:36 [ ADDR : EDIT/ DEL : REPLY ]