programing

사용자 정의 글꼴 및 XML 레이아웃(Android)

prostudy 2022. 5. 21. 08:53
반응형

사용자 정의 글꼴 및 XML 레이아웃(Android)

나는 안드로이드의 XML 파일을 사용하여 GUI 레이아웃을 정의하려고 한다.내가 알 수 있는 한, 당신의 위젯은 XML 파일에서 사용자 정의 글꼴(예: 자산/퐁/에 저장한 글꼴)을 사용해야 하며, 당신은 시스템에 설치된 글꼴만 사용할 수 있다.

나는 자바 코드에서 고유한 ID를 사용하여 각 위젯의 글꼴을 수동으로 변경할 수 있다는 것을 알고 있다.또는 자바에 있는 모든 위젯을 반복해서 변경할 수도 있지만, 이 작업은 매우 느릴 겁니다.

다른 방법이 뭐가 있지?사용자 정의 모양을 갖춘 위젯을 만드는 더 좋은 방법이 없을까?새로 추가하는 위젯마다 글꼴을 수동으로 변경할 필요는 특별히 없어.

여기서 배운 대로 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: (res/changes)

<?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

이 방법에는 심각한 기억력 문제가 있다.아래 체다밥의 코멘트를 참조하십시오.

나는 파티에 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;
}
}

사용자 지정 텍스트 보기:

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

Android O 프리뷰 릴리즈에서 가장 좋은 방법은 다음과 같다.
1.)res 폴더를 마우스 오른쪽 버튼으로 누르고 New > Android 리소스 디렉토리로 이동한다.더 뉴
리소스 디렉터리 창이 나타난다.
2.)리소스 유형 목록에서 글꼴을 선택한 다음 확인을 누르십시오.
3.)글꼴 폴더에 글꼴 파일을 추가하십시오.아래의 폴더 구조는 R.font.dancing_script, R.font.la_la, R.font.ba_ba를 생성한다.
4.)글꼴 파일을 두 번 눌러 편집기에서 파일의 글꼴을 미리 보십시오.

다음으로 우리는 글꼴 패밀리를 만들어야 한다.

1.)글꼴 폴더를 마우스 오른쪽 버튼으로 누르고 새로 만들기 >글꼴 리소스 파일로 이동한다.새 리소스 파일 창이 나타난다.
2.)파일 이름을 입력한 다음 확인을 누르십시오.새 글꼴 리소스 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"**/>

설명서의 내용

글꼴 사용

모든 단계가 정확하다.

연장하다TextView사용자 지정 속성을 지정하거나 Android:tag 속성을 사용하여 사용할 글꼴의 문자열을 전달하십시오.컨벤션은 내가 모든 폰트를 res/asset/fonts/폴더에 넣어 당신의 TextView 클래스가 어디에서 찾을 수 있는지 알 수 있도록 하는 것과 같이 컨벤션에 충실해야 할 것이다.그런 다음 생성자에서 수퍼콜 후에 글꼴을 수동으로 설정하십시오.

사용자 정의 글꼴을 사용하는 유일한 방법은 소스 코드를 통해서입니다.

Android는 리소스가 매우 제한된 기기에서 실행되며 글꼴에는 상당한 양의 RAM이 필요할 수 있다는 점을 기억하십시오.내장된 드로이드 글꼴은 특별히 제작되었으며, 메모하면 많은 문자와 장식이 누락되어 있다.

텍스트 뷰를 확장하고 긴 코드를 구현하지 않고 질문에 대한 간단한 답변이 있을 수 있다.

코드 :

 TextView tv = (TextView) findViewById(R.id.textview1);
    tv.setTypeface(Typeface.createFromAsset(getAssets(), "font.ttf"));

평소와 같이 사용자 지정 글꼴 파일을 자산 폴더에 배치하고 이렇게 해보십시오.그것은 나에게 효과가 있다.나는 단지 피터가 왜 이 간단한 것에 대해 그렇게 큰 코드를 주었는지, 아니면 옛날 버전으로 그의 대답을 주었는지 이해할 수 없다.

사용자 지정 클래스를 만들지 않고도 xml에서 정의 가능

style.xml

<style name="ionicons" parent="android:TextAppearance">
    <!-- Custom Attr-->
    <item name="fontPath">fonts/ionicons.ttf</item>
</style>

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/ionicons"
        android:text=""/>
</LinearLayout>

간단한 메모, 내가 항상 글꼴을 어디에 두어야 하는지 잊어버렸기 때문에 글꼴이 안에 있어야 한다.assets그리고 이 폴더는 다음과 같은 레벨에 위치한다.res그리고src, 나의 경우 그것은assets/fonts/ionicons.ttf

업데이트 이 메서드에 필요한 추가 루트 레이아웃xmlns:app="http://schemas.android.com/apk/res-auto"일하기 위해

업데이트 2 캘리그라피라는 이름의 라이브러리를 설치하지 않았음

피터의 대답이 최고지만 안드로이드의 styles.xml을 사용하여 앱의 모든 텍스트 뷰에 맞게 글꼴을 사용자 지정함으로써 개선할 수 있다.

내 코드가 여기에 있다.

글꼴을 사용자 지정하는 방법에는 다음 두 가지가 있다.

!!! 내 자산/자산/이란_nf.ttf의 사용자 지정 글꼴

방법 1 : Refreme Typeface.class || 최선의 방법

글꼴 오버라이드를 호출하십시오.클래스의 setDefaultFont()는 응용 프로그램을 확장하며, 이 코드로 인해 모든 소프트웨어 글꼴이 변경되며, Both 글꼴도 변경됨

AppController.java

public class AppController extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        //Initial Font
        FontsOverride.setDefaultFont(getApplicationContext(), "MONOSPACE", "fonts/iran_sans.ttf");

    }
}

글꼴오버라이드.java

public class FontsOverride {

    public static void setDefaultFont(Context context, String staticTypefaceFieldName, String fontAssetName) {
        final Typeface regular = Typeface.createFromAsset(context.getAssets(), fontAssetName);
        replaceFont(staticTypefaceFieldName, regular);
    }

    private static void replaceFont(String staticTypefaceFieldName, final Typeface newTypeface) {
        try {
            final Field staticField = Typeface.class.getDeclaredField(staticTypefaceFieldName);
            staticField.setAccessible(true);
            staticField.set(null, newTypeface);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

방법 2: setTypeface 사용

특수 뷰의 경우 setTypeface()로 전화하여 글꼴을 변경하십시오.

CTextView.java

public class CTextView extends TextView {

    public CTextView(Context context) {
        super(context);
        init(context,null);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context,attrs);
    }

    public void init(Context context, @Nullable AttributeSet attrs) {

        if (isInEditMode())
            return;

        // use setTypeface for change font this view
        setTypeface(FontUtils.getTypeface("fonts/iran_sans.ttf"));

    }
}

FontUtils.java

public class FontUtils {

    private static Hashtable<String, Typeface> fontCache = new Hashtable<>();

    public static Typeface getTypeface(String fontName) {
        Typeface tf = fontCache.get(fontName);
        if (tf == null) {
            try {
                tf = Typeface.createFromAsset(AppController.getInstance().getApplicationContext().getAssets(), fontName);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            fontCache.put(fontName, tf);
        }
        return tf;
    }

}

여기에 설명된 @put과 같은 사용자 정의 글꼴을 설정하는 방법을 보여주는 튜토리얼이 있다: http://responsiveandroid.com/2012/03/15/custom-fonts-in-android-widgets.html

그것은 또한 잠재적인 메모리 누수에 대한 고려를 가지고 있다. 또한 튜토리얼에서는 버튼에 사용자 정의 글꼴을 설정하는 예를 보여준다.

텍스트 보기 클래스를 쉽게 사용자 지정할 수 있다:-

그러니 먼저 해야 할 일은, 만들어라.Custom textview와 함께 연장된 학급.AppCompatTextView.

public class CustomTextView extends AppCompatTextView {
    private int mFont = FontUtils.FONTS_NORMAL;
    boolean fontApplied;

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

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, context);
    }

    public CustomTextView(Context context) {
        super(context);
        init(null, context);
    }

    protected void init(AttributeSet attrs, Context cxt) {
        if (!fontApplied) {
            if (attrs != null) {
                mFont = attrs.getAttributeIntValue(
                        "http://schemas.android.com/apk/res-auto", "Lato-Regular.ttf",
                        -1);
            }
            Typeface typeface = getTypeface();
            int typefaceStyle = Typeface.NORMAL;
            if (typeface != null) {
                typefaceStyle = typeface.getStyle();
            }
            if (mFont > FontUtils.FONTS) {
                typefaceStyle = mFont;
            }
            FontUtils.applyFont(this, typefaceStyle);
            fontApplied = true;
        }
    }
}

이제, 매번 사용자 지정 텍스트 보기 호출 및 속성에서 int 값을 가져올 것이다.int fontValue = attrs.getAttributeIntValue("http://schemas.android.com/apk/res-auto","Lato-Regular.ttf",-1).

아니면

xml에 설정한 getTypeface()도 뷰에서 얻을 수 있다.android:textStyle="bold|normal|italic"네가 하고 싶은 대로 해

자, 우리는 만든다.FontUtils.ttf 글꼴을 우리의 시야에 설정하기 위해.

public class FontUtils {

    public static final int FONTS = 1;
    public static final int FONTS_NORMAL = 2;
    public static final int FONTS_BOLD = 3;
    public static final int FONTS_BOLD1 = 4;

    private static Map<String, Typeface> TYPEFACE = new HashMap<String, Typeface>();

    static Typeface getFonts(Context context, String name) {
        Typeface typeface = TYPEFACE.get(name);
        if (typeface == null) {
            typeface = Typeface.createFromAsset(context.getAssets(), name);
            TYPEFACE.put(name, typeface);
        }
        return typeface;
    }

    public static void applyFont(TextView tv, int typefaceStyle) {

        Context cxt = tv.getContext();
        Typeface typeface;

        if(typefaceStyle == Typeface.BOLD_ITALIC) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Normal.ttf");
        }else if (typefaceStyle == Typeface.BOLD || typefaceStyle == SD_FONTS_BOLD|| typefaceStyle == FONTS_BOLD1) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-SemiBold.ttf");
        } else if (typefaceStyle == Typeface.ITALIC) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Thin.ttf");
        } else {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Normal.ttf");
        }
        if (typeface != null) {
            tv.setTypeface(typeface);
        }
    }
}

안드로이드 8.0(API 레벨 26)부터 XML의 사용자 정의 글꼴을 사용할 수 있다는 것을 알면 유용할 수 있다.

사용자 정의 글꼴은 다음과 같은 방법으로 전체 응용 프로그램에 적용할 수 있다.

  1. 폴더에 글꼴 넣기res/font.

  2. res/values/styles.xml응용 프로그램 테마에 사용. <style name="AppTheme" parent="{whatever you like}"> <item name="android:fontFamily">@font/myfont</item> </style>

폰티네이터는 Android-Library로 사용자 정의 글꼴을 쉽게 사용할 수 있다.https://github.com/svendvd/Fontinator

TextView를 확장하여 위젯을 작성하거나 위젯 레이아웃에서 사용할 수 없음: http://developer.android.com/guide/topics/appwidgets/index.html

참조URL: https://stackoverflow.com/questions/2376250/custom-fonts-and-xml-layouts-android

반응형