액티비티
레이아웃
TextView에 외부 폰트를 적용하려면 다음 절차를 거쳐야 합니다.
- /assets 폴더에 적용하려는 폰트 파일 넣어주기
- Typeface.createFromAsset(AssetManager, String); 을 사용하여 폰트 로드
- 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() 오버라이드 | 거의 지연 없음 |
사양의 차이인건진 몰라도, 생각보다 딜레이가 거의 없어서 좀 놀랐습니다. 하지만, 저사양 단말기에서 이를 실행한다면 첫 번째 방법의 경우 실제로 이를 사용하기엔 문제가 좀 있지 않을까 싶습니다.
'안드로이드 개발 팁 > UI' 카테고리의 다른 글
| RecyclerView에서 스크롤바를 표시하는 방법 (1) | 2015.07.16 |
|---|---|
| 선택 가능한 항목(리스트, 버튼)의 배경에 머티리얼 디자인 적용하기 (0) | 2015.03.12 |
| Landscape 모드에서 EditText 입력시 전체화면으로 뜨지 않게 하려면? (6) | 2011.04.20 |
| 배경이 투명한 액티비티를 만드려면? (3) | 2009.11.28 |
| 안드로이드 위젯, 아무렇게나 만들지 마세요~ ^^; (0) | 2009.05.10 |
CustomFont.zip