[java] 맞춤 글꼴 및 XML 레이아웃 (Android)

Android에서 XML 파일을 사용하여 GUI 레이아웃을 정의하려고합니다. 내가 알 수있는 한 위젯이 XML 파일의 사용자 정의 글꼴 (예 : 자산 / 글꼴 /에 배치 된 글꼴)을 사용해야하고 시스템 설치 글꼴 만 사용할 수 있도록 지정할 수있는 방법이 없습니다.

Java 코드에서 고유 ID를 사용하여 각 위젯의 글꼴을 수동으로 변경할 수 있음을 알고 있습니다. 또는 Java의 모든 위젯을 반복 하여이 변경을 수행 할 수는 있지만 아마도 매우 느릴 것입니다.

다른 옵션이 있습니까? 사용자 정의 모양의 위젯을 만드는 더 좋은 방법이 있습니까? 특히 내가 추가하는 모든 새 위젯에 대해 수동으로 글꼴을 변경하고 싶지 않습니다.



답변

여기서 배운 것처럼 TextView를 확장하여 사용자 정의 글꼴을 설정할 수 있습니다 .

TextViewPlus.java :

package com.example;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;

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

        setTypeface(tf);  
        return true;
    }

}

attrs.xml : (값 / 값)

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

main.xml :

<?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/com.example"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.example.TextViewPlus
        android:id="@+id/textViewPlus1"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:text="@string/showingOffTheNewTypeface"
        foo:customFont="saxmono.ttf">
    </com.example.TextViewPlus>
</LinearLayout>

“saxmono.ttf”를 자산 폴더 에 넣습니다 .

업데이트 8/1/13

이 방법에는 심각한 메모리 문제가 있습니다. 아래의 chedabob의 의견을 참조하십시오 .


답변

나는 파티에 3 년 늦었다. (그러나 이것은이 포스트를 우연히 발견 할 수있는 누군가에게 유용 할 수있다.

서체를 캐시하고 XML에서 사용자 정의 서체를 지정할 수있는 라이브러리를 작성했습니다. 여기 에서 라이브러리를 찾을 수 있습니다 .

XML 레이아웃을 사용할 때의 모습은 다음과 같습니다.

<com.mobsandgeeks.ui.TypefaceTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world"
    geekui:customTypeface="fonts/custom_font.ttf" />


답변

약간 늦을 수 있지만 메모리 누수를 피하기 위해 사용자 정의 서체를 반환하는 싱글 톤 클래스를 만들어야합니다.

TypeFace 클래스 :

public class OpenSans {

private static OpenSans instance;
private static Typeface typeface;

public static OpenSans getInstance(Context context) {
    synchronized (OpenSans.class) {
        if (instance == null) {
            instance = new OpenSans();
            typeface = Typeface.createFromAsset(context.getResources().getAssets(), "open_sans.ttf");
        }
        return instance;
    }
}

public Typeface getTypeFace() {
    return typeface;
}
}

맞춤 TextView :

public class NativelyCustomTextView extends TextView {

    public NativelyCustomTextView(Context context) {
        super(context);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

    public NativelyCustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

    public NativelyCustomTextView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

}

xml로 :

<com.yourpackage.views.NativelyCustomTextView
            android:id="@+id/natively_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_margin="20dp"
            android:text="@string/natively"
            android:textSize="30sp" /> 

프로그래밍 방식으로 :

TextView programmaticallyTextView = (TextView) 
       findViewById(R.id.programmatically_text_view);

programmaticallyTextView.setTypeface(OpenSans.getInstance(this)
                .getTypeFace());


답변

오래된 질문이지만 좋은 해결책을 찾기 위해 자신의 검색을 시작하기 전에이 대답을 읽으십시오. 서예android:fontFamily속성을 확장하여 다음과 같이 자산 폴더에 사용자 정의 글꼴에 대한 지원을 추가합니다.

<TextView 
  android:text="@string/hello_world"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:fontFamily="fonts/Roboto-Bold.ttf"/>

그것을 활성화하기 위해해야 ​​할 유일한 것은 사용중인 활동의 컨텍스트에 첨부하는 것입니다.

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(new CalligraphyContextWrapper(newBase));
}

자신의 사용자 정의 속성을 지정하여 바꿀 수도 있습니다 android:fontFamily

또한 AppTheme을 포함한 테마에서도 작동합니다.


답변

DataBinding 사용 :

@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"/>

글꼴 파일은 assets/fonts/


답변

추가하려는 서체가 하나만 있고 더 적은 코드를 작성하려는 경우 특정 글꼴에 대한 전용 TextView를 만들 수 있습니다. 아래 코드를 참조하십시오.

package com.yourpackage;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;

public class FontTextView extends TextView {
    public static Typeface FONT_NAME;


    public FontTextView(Context context) {
        super(context);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
    public FontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
    public FontTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
}

main.xml에서 다음과 같이 textView를 추가 할 수 있습니다.

<com.yourpackage.FontTextView
    android:id="@+id/tvTimer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="" />


답변

안드로이드 O의 프리뷰 버전에서 그것을 할 수있는 가장 좋은 방법은이 방법
1)을 마우스 오른쪽 단추로 클릭하고 폴더 고해상도 와 이동 새로 만들기> 안드로이드 자원 디렉토리를 . New
Resource Directory 창이 나타납니다.
리소스 유형 목록에서 font 를 선택한 다음 확인을 클릭합니다.
3.) 폰트 폴더에 폰트 파일을 추가하십시오 . 아래의 폴더 구조는 R.font.dancing_script, R.font.la_la 및 R.font.ba_ba를 생성합니다.
4.) 글꼴 파일을 두 번 클릭 하여 편집기에서 파일의 글꼴을 미리 봅니다.

다음으로 폰트 패밀리를 만들어야합니다

1.) 글꼴 폴더를 마우스 오른쪽 단추로 클릭하고 새로 작성> 글꼴 자원 파일 로 이동 하십시오 . 새 리소스 파일 창이 나타납니다. 파일 이름을
입력 한 다음 확인을 클릭 합니다. 새 글꼴 리소스 XML이 편집기에서 열립니다.
3) 각 글꼴 파일, 스타일 및 가중치 속성을 글꼴 태그 요소에 포함하십시오. 다음 XML은 글꼴 자원 XML에 글꼴 관련 속성을 추가하는 방법을 보여줍니다.

<?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/hey_regular" />
    <font
    android:fontStyle="italic"
    android:fontWeight="400"
    android:font="@font/hey_bababa" />
</font-family>

TextView에 글꼴 추가하기 :

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

설명서에서와 같이

폰트로 작업하기

모든 단계가 정확합니다.