Saya telah menambahkan file font khusus ke folder aset / font saya. Bagaimana cara menggunakannya dari XML saya?
Saya dapat menggunakannya dari kode sebagai berikut:
TextView text = (TextView) findViewById(R.id.textview03);
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/Molot.otf");
text.setTypeface(tf);
Tidak bisakah saya melakukannya dari XML menggunakan android:typeface="/fonts/Molot.otf"
atribut?
Jawaban:
Jawaban singkat: Tidak. Android tidak memiliki dukungan bawaan untuk menerapkan font khusus ke widget teks melalui XML.
Namun, ada solusi yang tidak terlalu sulit untuk diterapkan.
Pertama
Anda harus menentukan gaya Anda sendiri. Di folder / res / values Anda, buka / buat file attrs.xml dan tambahkan objek yang dapat dideklarasikan bergaya seperti ini:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="FontText"> <attr name="typefaceAsset" format="string"/> </declare-styleable> </resources>
Kedua
Dengan asumsi Anda ingin sering menggunakan widget ini, Anda harus menyiapkan cache sederhana untuk
Typeface
objek yang dimuat , karena memuatnya dari memori dengan cepat dapat memakan waktu. Sesuatu seperti:public class FontManager { private static FontManager instance; private AssetManager mgr; private Map<String, Typeface> fonts; private FontManager(AssetManager _mgr) { mgr = _mgr; fonts = new HashMap<String, Typeface>(); } public static void init(AssetManager mgr) { instance = new FontManager(mgr); } public static FontManager getInstance() { if (instance == null) { // App.getContext() is just one way to get a Context here // getContext() is just a method in an Application subclass // that returns the application context AssetManager assetManager = App.getContext().getAssets(); init(assetManager); } return instance; } public Typeface getFont(String asset) { if (fonts.containsKey(asset)) return fonts.get(asset); Typeface font = null; try { font = Typeface.createFromAsset(mgr, asset); fonts.put(asset, font); } catch (Exception e) { } if (font == null) { try { String fixedAsset = fixAssetFilename(asset); font = Typeface.createFromAsset(mgr, fixedAsset); fonts.put(asset, font); fonts.put(fixedAsset, font); } catch (Exception e) { } } return font; } private String fixAssetFilename(String asset) { // Empty font filename? // Just return it. We can't help. if (TextUtils.isEmpty(asset)) return asset; // Make sure that the font ends in '.ttf' or '.ttc' if ((!asset.endsWith(".ttf")) && (!asset.endsWith(".ttc"))) asset = String.format("%s.ttf", asset); return asset; } }
Yang ini akan memungkinkan Anda untuk menggunakan ekstensi file .ttc, tetapi belum teruji.
Ketiga
Buat kelas baru yang merupakan subkelas
TextView
. Contoh khusus ini memperhitungkan jenis huruf XML yang ditentukan (bold
,,italic
dll.) Dan menerapkannya ke font (dengan asumsi Anda menggunakan file .ttc)./** * TextView subclass which allows the user to define a truetype font file to use as the view's typeface. */ public class FontText extends TextView { public FontText(Context context) { this(context, null); } public FontText(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FontText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); if (isInEditMode()) return; TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FontText); if (ta != null) { String fontAsset = ta.getString(R.styleable.FontText_typefaceAsset); if (!TextUtils.isEmpty(fontAsset)) { Typeface tf = FontManager.getInstance().getFont(fontAsset); int style = Typeface.NORMAL; float size = getTextSize(); if (getTypeface() != null) style = getTypeface().getStyle(); if (tf != null) setTypeface(tf, style); else Log.d("FontText", String.format("Could not create a font from asset: %s", fontAsset)); } } } }
Akhirnya
Ganti contoh
TextView
dalam XML Anda dengan nama kelas yang memenuhi syarat. Deklarasikan namespace kustom Anda seperti yang Anda lakukan pada namespace Android. Perhatikan bahwa "typefaceAsset" harus mengarah ke file .ttf atau .ttc yang ada di direktori / assets Anda.<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.FontText android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="This is a custom font text" custom:typefaceAsset="fonts/AvenirNext-Regular.ttf"/> </RelativeLayout>
sumber
Berikut adalah contoh kode yang melakukan ini. Saya memiliki font yang ditentukan dalam variabel akhir statis dan file font ada di direktori aset.
public class TextViewWithFont extends TextView { public TextViewWithFont(Context context, AttributeSet attrs) { super(context, attrs); this.setTypeface(MainActivity.typeface); } public TextViewWithFont(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); this.setTypeface(MainActivity.typeface); } public TextViewWithFont(Context context) { super(context); this.setTypeface(MainActivity.typeface); } }
sumber
Buat TextView kustom Anda milik font yang ingin Anda gunakan. Di kelas ini, saya menggunakan bidang mTypeface statis untuk menyimpan jenis huruf dalam cache (untuk kinerja yang lebih baik)
public class HeliVnTextView extends TextView { /* * Caches typefaces based on their file path and name, so that they don't have to be created every time when they are referenced. */ private static Typeface mTypeface; public HeliVnTextView(final Context context) { this(context, null); } public HeliVnTextView(final Context context, final AttributeSet attrs) { this(context, attrs, 0); } public HeliVnTextView(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); if (mTypeface == null) { mTypeface = Typeface.createFromAsset(context.getAssets(), "HelveticaiDesignVnLt.ttf"); } setTypeface(mTypeface); } }
Dalam file xml:
<java.example.HeliVnTextView android:id="@+id/textView1" android:layout_width="0dp" ... />
Di kelas java:
HeliVnTextView title = new HeliVnTextView(getActivity()); title.setText(issue.getName());
sumber
Aktivitas mengimplementasikan LayoutInflater.Factory2 yang menyediakan callback pada setiap View yang dibuat. Anda dapat mengatur gaya TextView dengan atribut font Family kustom, memuat tipografi sesuai permintaan dan memanggil setTypeface pada tampilan teks yang dibuat secara otomatis.
Sayangnya karena hubungan arsitektural instans Inflater relatif terhadap Aktivitas dan Windows, pendekatan paling sederhana untuk menggunakan font khusus di android adalah dengan menyimpan font yang dimuat di cache pada level Aplikasi.
Basis kode sampel ada di sini:
https://github.com/leok7v/android-textview-custom-fonts
<style name="Baroque" parent="@android:style/TextAppearance.Medium"> <item name="android:layout_width">fill_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:textColor">#F2BAD0</item> <item name="android:textSize">14pt</item> <item name="fontFamily">baroque_script</item> </style> <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res/custom.fonts" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView style="@style/Baroque" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/sample_text" />
menghasilkan
sumber
Bukan ide yang baik untuk menggunakan font khusus dalam xml karena fakta ini, Anda harus melakukannya secara terprogram untuk menghindari kebocoran memori!
sumber
Mungkin Anda dapat menggunakan refleksi untuk menyuntikkan / meretas font Anda ke dalam daftar statis font yang tersedia saat aplikasi Anda dibuat? Saya tertarik dengan umpan balik dari orang lain jika ini benar-benar ide yang buruk atau jika ini adalah solusi yang bagus - tampaknya ini akan menjadi salah satu yang ekstrim ...
Saya dapat memasukkan jenis huruf khusus saya ke dalam daftar jenis huruf sistem dengan nama keluarga font saya sendiri, kemudian menentukan nama keluarga font khusus itu ("brush-script") sebagai nilai android: FontFamily pada TextView standar bekerja di LG saya G4 menjalankan Android 6.0.
public class MyApplication extends android.app.Application { @Override public void onCreate() { super.onCreate(); Typeface font = Typeface.createFromAsset(this.getResources().getAssets(),"fonts/brush-script.ttf"); injectTypeface("brush-script", font); } private boolean injectTypeface(String fontFamily, Typeface typeface) { try { Field field = Typeface.class.getDeclaredField("sSystemFontMap"); field.setAccessible(true); Object fieldValue = field.get(null); Map<String, Typeface> map = (Map<String, Typeface>) fieldValue; map.put(fontFamily, typeface); return true; } catch (Exception e) { Log.e("Font-Injection", "Failed to inject typeface.", e); } return false; } }
Dalam tata letak saya
<TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Fancy Text" android:fontFamily="brush-script"/>
sumber
MyApplication
kelas perlu dipanggil?public class CustomTextView extends TextView { private static final String TAG = "TextView"; public CustomTextView(Context context) { super(context); } public CustomTextView(Context context, AttributeSet attrs) { super(context, attrs); setCustomFont(context, attrs); } public CustomTextView(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.CustomTextView); String customFont = a.getString(R.styleable.CustomTextView_customFont); setCustomFont(ctx, customFont); a.recycle(); } public boolean setCustomFont(Context ctx, String fontName) { Typeface typeface = null; try { if(fontName == null){ fontName = Constants.DEFAULT_FONT_NAME; } typeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/" + fontName); } catch (Exception e) { Log.e(TAG, "Unable to load typeface: "+e.getMessage()); return false; } setTypeface(typeface); return true; } }
dan tambahkan deklarabel di attrs.xml
<declare-styleable name="CustomTextView"> <attr name="customFont" format="string"/> </declare-styleable>
lalu tambahkan suka customFont Anda
app:customFont="arial.ttf"
sumber
Saya tahu ini adalah pertanyaan lama, tetapi saya telah menemukan solusi yang jauh lebih mudah.
Pertama-tama deklarasikan TextView Anda dalam xml seperti biasa. Letakkan font Anda (TTF atau TTC) di folder aset
Kemudian setel jenis huruf untuk tampilan teks Anda dalam metode onCreate.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_name); TextView textView = findViewById(R.id.my_textView); Typeface typeface = Typeface.createFromAsset(getAssets(), "fontName.ttf"); textView.setTypeface(typeface); }
Selesai.
sumber
Solusi terbaik adalah menggunakan (akhirnya) yang diperkenalkan oleh Google fitur font kustom asli dalam XML. Tetapi Anda harus menargetkan API 26. Ini mendukung API 16+
https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml
sumber
bukannya xmlns: custom = "schemas.android.com/tools"; Anda harus menggunakan: xmlns: custom = "schemas.android.com/apk/res-auto"; untuk menggunakan atribut bergaya. Saya membuat perubahan ini dan berhasil sekarang.
sumber