Bagaimana cara mengubah font pada TextView?

Jawaban:

342

Pertama, defaultnya bukan Arial. Standarnya adalah Droid Sans.

Kedua, untuk mengubah font bawaan yang berbeda, gunakan android:typefacedalam tata letak XML atau setTypeface()di Jawa.

Ketiga, tidak ada font Helvetica di Android. Pilihan bawaan adalah Droid Sans ( sans), Droid Sans Mono ( monospace), dan Droid Serif ( serif). Meskipun Anda dapat menggabungkan font Anda sendiri dengan aplikasi Anda dan menggunakannya melalui setTypeface(), ingatlah bahwa file font besar dan, dalam beberapa kasus, memerlukan perjanjian lisensi (misalnya, Helvetica, font Linotype ).

EDIT

Bahasa desain Android bergantung pada alat tipografi tradisional seperti skala, ruang, ritme, dan penjajaran dengan kisi yang mendasarinya. Keberhasilan penyebaran alat-alat ini sangat penting untuk membantu pengguna dengan cepat memahami layar informasi. Untuk mendukung penggunaan tipografi seperti itu, Ice Cream Sandwich memperkenalkan keluarga tipe baru bernama Roboto, yang dibuat khusus untuk persyaratan UI dan layar resolusi tinggi.

Kerangka kerja TextView saat ini menawarkan Roboto dalam bobot yang tipis, ringan, teratur, dan tebal, serta gaya miring untuk setiap bobot. Kerangka kerja ini juga menawarkan varian Roboto Condensed dalam bobot reguler dan tebal, bersama dengan gaya miring untuk setiap bobot.

Setelah ICS, android menyertakan gaya font Roboto, Read more Roboto

EDIT 2

Dengan munculnya Support Library 26, Android sekarang mendukung font khusus secara default. Anda dapat menyisipkan font baru di res / font yang dapat diatur ke TextViews secara individu baik dalam XML atau secara terprogram. Font default untuk seluruh aplikasi juga dapat diubah dengan mendefinisikannya styles.xml Dokumentasi pengembang android memiliki panduan yang jelas tentang hal ini di sini

CommonsWare
sumber
6
Tidak ada cara untuk mengatur font dalam XML? Mengapa?
Jonny
5
@ Johnny Kamu benar-benar bisa. Anda sedang membuat kelas yang memperluas TextView dan memanggil setTypeface dari konstruktor.
Mark Phillip
bagaimana melakukannya di Layout XML?
M. Usman Khan
2
@manman: Anda memerlukan perpustakaan pihak ketiga, seperti Kaligrafi: github.com/chrisjenx/Calligraphy
CommonsWare
Pengaturan jenis huruf menggunakan kode java sulit karena beberapa baris, saya telah membuat perpustakaan untuk mengatur font khusus. Anda dapat menemukan penggunaan perpustakaan dalam jawaban ini stackoverflow.com/a/42001474/4446392
Chathura Jayanath
254

Pertama-tama unduh .ttffile font yang Anda butuhkan ( arial.ttf). Tempatkan di assets folder. (Folder aset dalam membuat folder baru bernama font dan letakkan di dalamnya.) Gunakan kode berikut untuk menerapkan font ke Anda TextView:

Typeface type = Typeface.createFromAsset(getAssets(),"fonts/arial.ttf"); 
textView.setTypeface(type);
HjK
sumber
Dear Mayur, Ada rekomendasi di mana mendapatkan file .ttf ini?
Lonelearner
3
Dear @lonelearner Anda dapat mengunduh file font (.ttf) gratis di 1001freefonts.com atau hanya google "Font gratis"
ymerdrengene
10
Bagi mereka yang menggunakan Android Studio dan tidak dapat menemukan folder "aset", lihat pertanyaan ini . Jawaban singkat: src/main/assets/fonts/.
adamdport
51
Typeface tf = Typeface.createFromAsset(getAssets(),
        "fonts/DroidSansFallback.ttf");
TextView tv = (TextView) findViewById(R.id.CustomFontText);
tv.setTypeface(tf);
Android Girl
sumber
33

Anda mungkin ingin membuat kelas statis yang akan berisi semua font. Dengan begitu, Anda tidak akan membuat font berkali-kali yang mungkin berdampak buruk pada kinerja . Pastikan Anda membuat sub-folder yang disebut " fonts " di bawah folder " assets ".

Lakukan sesuatu seperti:

public class CustomFontsLoader {

public static final int FONT_NAME_1 =   0;
public static final int FONT_NAME_2 =   1;
public static final int FONT_NAME_3 =   2;

private static final int NUM_OF_CUSTOM_FONTS = 3;

private static boolean fontsLoaded = false;

private static Typeface[] fonts = new Typeface[3];

private static String[] fontPath = {
    "fonts/FONT_NAME_1.ttf",
    "fonts/FONT_NAME_2.ttf",
    "fonts/FONT_NAME_3.ttf"
};


/**
 * Returns a loaded custom font based on it's identifier. 
 * 
 * @param context - the current context
 * @param fontIdentifier = the identifier of the requested font
 * 
 * @return Typeface object of the requested font.
 */
public static Typeface getTypeface(Context context, int fontIdentifier) {
    if (!fontsLoaded) {
        loadFonts(context);
    }
    return fonts[fontIdentifier];
}


private static void loadFonts(Context context) {
    for (int i = 0; i < NUM_OF_CUSTOM_FONTS; i++) {
        fonts[i] = Typeface.createFromAsset(context.getAssets(), fontPath[i]);
    }
    fontsLoaded = true;

}
}

Dengan cara ini, Anda bisa mendapatkan font dari mana saja di aplikasi Anda.

Daniel L.
sumber
1
Bung yang luar biasa! Ini adalah keindahan OOP. Kerja bagus! :)
Joshua Michael Wagoner
Bagaimana saya menggunakan kelas ini?
Jack
Anda perlu menempatkan kode ini di proyek Anda, menyesuaikannya dengan font Anda dan kemudian menggunakan metode statis getTypeface (..) dari mana-mana di aplikasi Anda.
Daniel L.
Saya menggunakan solusi serupa, tetapi menambahkan caching untuk meningkatkan kinerja .... dalam hal apa pun, apakah Anda menghadapi situasi di mana font berfungsi pada beberapa ponsel dan tidak pada yang lain?
RJFares
20

Praktik terbaik yang pernah ada

TextViewPlus.java:

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

        setTypeface(typeface);
        return true;
    }
}

attrs.xml: (Tempat menempatkan res / nilai )

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

Cara Penggunaan:

<?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-auto"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.mypackage.TextViewPlus
        android:id="@+id/textViewPlus1"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:text="@string/showingOffTheNewTypeface"
        foo:customFont="my_font_name_regular.otf">
    </com.mypackage.TextViewPlus>
</LinearLayout>

Semoga ini bisa membantu Anda.

Hiren Patel
sumber
1
Mengapa subklasifikasi TextView merupakan praktik terbaik?
Stealth Rabbi
@Stealth Rabbi, di sini kita dapat mengirimkan font khusus dengan xml saja, tidak perlu menulis kode java khusus untuk setiap textview.
Hiren Patel
Ada perpustakaan untuk itu. Cukup tambahkan font Anda di bawah folder aset dan nyatakan dalam XML. github.com/febaisi/CustomTextView
febaisi
Pustaka Anda terlihat baik-baik saja, tetapi satu-satunya masalah adalah bahwa itu untuk android
21+
@febaisi seperti yang saya lihat dalam contoh lib Anda raw.githubusercontent.com/febaisi/CustomTextView/master/wiki/…
Mr.Q
17

Jawaban di atas benar. Pastikan Anda membuat sub-folder yang disebut "fonts" di bawah folder "assets" jika Anda menggunakan potongan kode itu.

VJ Vélan Solutions
sumber
1
Komentar Anda berlebihan. Penjelasan di atas mengatakan dengan tepat apa yang Anda katakan, dan banyak lagi ...
Joshua Michael Wagoner
14

Cara lain untuk menggabungkan pembuatan font ...

public class Font {
  public static final Font  PROXIMA_NOVA    = new Font("ProximaNovaRegular.otf");
  public static final Font  FRANKLIN_GOTHIC = new Font("FranklinGothicURWBoo.ttf");
  private final String      assetName;
  private volatile Typeface typeface;

  private Font(String assetName) {
    this.assetName = assetName;
  }

  public void apply(Context context, TextView textView) {
    if (typeface == null) {
      synchronized (this) {
        if (typeface == null) {
          typeface = Typeface.createFromAsset(context.getAssets(), assetName);
        }
      }
    }
    textView.setTypeface(typeface);
  }
}

Dan kemudian digunakan dalam aktivitas Anda ...

myTextView = (TextView) findViewById(R.id.myTextView);
Font.PROXIMA_NOVA.apply(this, myTextView);

Pikiran Anda, ini idiom penguncian dua kali diperiksa dengan bidang volatil hanya berfungsi dengan benar dengan model memori yang digunakan di Java 1.5+.

Chris Aitchison
sumber
Mengapa jawaban ini hanya memiliki 1 upvote dan yang di atas memiliki 15? Apa yang membuat yang lain lebih baik? Menurut saya yang ini lebih lurus menggunakan prinsip singleton ...?
Koen Demonie
Baru saja melihat bahwa Anda memiliki konstruktor untuk publik, saya akan menjadikannya pribadi karena Anda tidak memerlukan akses ke sana. Anda menggunakan
von
Benar-benar harus menjadi konstruktor pribadi. Terlihat dengan baik :) Akan diedit!
Chris Aitchison
12

Praktik terbaik adalah menggunakan Android Support Library versi 26.0.0 atau lebih tinggi.

LANGKAH 1: tambahkan file font

  1. Dalam folder res, buat kamus sumber daya font baru
  2. Tambahkan file font ( .ttf , .orf )

Misalnya, ketika file font adalah helvetica_neue.ttf yang akan menghasilkan R.font.helvetica_neue

LANGKAH 2: buat keluarga font

  1. Dalam folder font tambahkan file sumber daya baru
  2. Lampirkan setiap file font, style, dan atribut weight dalam elemen.

Sebagai contoh:

<?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/helvetica_neue" />
</font-family>

LANGKAH 3: gunakan itu

Dalam tata letak xml:

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

Atau tambahkan font ke gaya:

<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
    <item name="android:fontFamily">@font/lobster</item>
</style>

Untuk lebih banyak contoh, Anda dapat mengikuti dokumentasi:

Bekerja dengan font

Marek Rzeźniczek
sumber
7

Ini agak tua, tapi saya sedikit meningkatkan kelas CustomFontLoader dan saya ingin membagikannya sehingga dapat membantu. Buat kelas baru dengan kode ini.

 import android.content.Context;
 import android.graphics.Typeface;

public enum FontLoader {

ARIAL("arial"),
TIMES("times"),
VERDANA("verdana"),
TREBUCHET("trbuchet"),
GEORGIA("georgia"),
GENEVA("geneva"),
SANS("sans"),
COURIER("courier"),
TAHOMA("tahoma"),
LUCIDA("lucida");   


private final String name;
private Typeface typeFace;


private FontLoader(final String name) {
    this.name = name;

    typeFace=null;  
}

public static Typeface getTypeFace(Context context,String name){
    try {
        FontLoader item=FontLoader.valueOf(name.toUpperCase(Locale.getDefault()));
        if(item.typeFace==null){                
            item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");                 
        }           
        return item.typeFace;
    } catch (Exception e) {         
        return null;
    }                   
}
public static Typeface getTypeFace(Context context,int id){
    FontLoader myArray[]= FontLoader.values();
    if(!(id<myArray.length)){           
        return null;
    } 
    try {
        if(myArray[id].typeFace==null){     
            myArray[id].typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+myArray[id].name+".ttf");                       
        }       
        return myArray[id].typeFace;    
    }catch (Exception e) {          
        return null;
    }   

}

public static Typeface getTypeFaceByName(Context context,String name){      
    for(FontLoader item: FontLoader.values()){              
        if(name.equalsIgnoreCase(item.name)){
            if(item.typeFace==null){
                try{
                    item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");     
                }catch (Exception e) {          
                    return null;
                }   
            }
            return item.typeFace;
        }               
    }
    return null;
}   

public static void loadAllFonts(Context context){       
    for(FontLoader item: FontLoader.values()){              
        if(item.typeFace==null){
            try{
                item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");     
            }catch (Exception e) {
                item.typeFace=null;
            }   
        }                
    }       
}   
}

Kemudian gunakan saja kode ini pada tampilan teks Anda:

 Typeface typeFace=FontLoader.getTypeFace(context,"arial");  
 if(typeFace!=null) myTextView.setTypeface(typeFace);
Alan
sumber
5

Saya akhirnya mendapat solusi yang sangat mudah untuk ini.

  1. gunakan pustaka Dukungan ini di tingkat tingkat aplikasi ,

    compile 'com.android.support:appcompat-v7:26.0.2'
    compile 'com.android.support:support-v4:26.0.2'
  2. kemudian buat direktori bernama "font" di dalam folder res

  3. letakkan file font (ttf) di direktori font itu, ingatlah konvensi penamaan [egname tidak boleh mengandung karakter khusus, karakter huruf besar dan spasi atau tab]
  4. Setelah itu, referensi font dari xml seperti ini

            <Button
            android:id="@+id/btn_choose_employee"
            android:layout_width="140dp"
            android:layout_height="40dp"
            android:layout_centerInParent="true"
            android:background="@drawable/rounded_red_btn"
            android:onClick="btnEmployeeClickedAction"
            android:text="@string/searching_jobs"
            android:textAllCaps="false"
            android:textColor="@color/white"
            android:fontFamily="@font/times_new_roman_test"
            />

Dalam contoh ini, times_new_roman_test adalah file font ttf dari direktori font tersebut

Shamsul Arefin Sajib
sumber
4
import java.lang.ref.WeakReference;
import java.util.HashMap;

import android.content.Context;
import android.graphics.Typeface;

public class FontsManager {

    private static FontsManager instance;

    private static HashMap<String, WeakReference<Typeface>> typefaces = new HashMap<String, WeakReference<Typeface>>();

    private static Context context;

    private FontsManager(final Context ctx) {
        if (context == null) {
            context = ctx;
        }
    }

    public static FontsManager getInstance(final Context appContext) {
        if (instance == null) {
            instance = new FontsManager(appContext);
        }
        return instance;
    }

    public static FontsManager getInstance() {
        if (instance == null) {
            throw new RuntimeException(
                    "Call getInstance(Context context) at least once to init the singleton properly");
        }
        return instance;
    }

    public Typeface getFont(final String assetName) {
        final WeakReference<Typeface> tfReference = typefaces.get(assetName);
        if (tfReference == null || tfReference.get() == null) {
            final Typeface tf = Typeface.createFromAsset(context.getResources().getAssets(),
                    assetName);
            typefaces.put(assetName, new WeakReference<Typeface>(tf));
            return tf;
        }
        return tfReference.get();
    }

}

Dengan cara ini, Anda bisa membuat tampilan yang mewarisi dari TextView dan memanggil setTypeface pada konstruktornya.

Charlie-Blake
sumber
1
Halo, mengapa menggunakan WeakReference untuk memegang objek TypeFace?
Malas
3

Ketika font Anda disimpan di dalam, res/asset/fonts/Helvetica.ttfgunakan yang berikut ini:

Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/Helvetica.ttf"); 
txt.setTypeface(tf);

Atau, jika file font Anda disimpan di dalam, res/font/helvetica.ttfgunakan yang berikut ini:

Typeface tf = ResourcesCompat.getFont(this,R.font.helvetica);
txt.setTypeface(tf);
Pankaj Lilan
sumber
2
Terima kasih, sedang mencari bagian di mana Anda memilikinya di folder res!
Mikkel Larsen
2

dapatkan font dari aset dan atur untuk semua anak

public static void overrideFonts(final Context context, final View v) {
    try {
        if (v instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) v;
            for (int i = 0; i < vg.getChildCount(); i++) {
                View child = vg.getChildAt(i);
                overrideFonts(context, child);
         }
        } else if (v instanceof TextView ) {
            ((TextView) v).setTypeface(Typeface.createFromAsset(context.getAssets(),"DroidNaskh.ttf"));// "BKOODB.TTF"));
        }
    } catch (Exception e) {
 }
 } 
Manian Rezaee
sumber
2
  1. tambahkan class FontTextView.java:


public class FontTextView extends TextView {
    String fonts[] = {"HelveticaNeue.ttf", "HelveticaNeueLight.ttf", "motschcc.ttf", "symbol.ttf"};

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

    public FontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (!isInEditMode()) {
            init(attrs);
        }

    }

    public FontTextView(Context context) {
        super(context);
        if (!isInEditMode()) {
            init(null);
        }
    }

    private void init(AttributeSet attrs) {
        if (attrs != null) {
            TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.FontTextView);
            if (a.getString(R.styleable.FontTextView_font_type) != null) {
                String fontName = fonts[Integer.valueOf(a.getString(R.styleable.FontTextView_font_type))];

                if (fontName != null) {
                    Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/" + fontName);
                    setTypeface(myTypeface);
                }
                a.recycle();
            }
        }
    }
}


  1. tambahkan ke font perpustakaan aset
    masukkan deskripsi gambar di sini


  1. tambahkan ke attrs.xml, Jumlahnya harus dalam urutan di kelas array.

    <declare-styleable name="FontTextView">
    <attr name="font_type" format="enum">
        <enum name="HelveticaNeue" value="0"/>
        <enum name="HelveticaNeueLight" value="1"/>
        <enum name="motschcc" value="2"/>
        <enum name="symbol" value="3"/>
    </attr>


  1. Pilih font dari daftar
    masukkan deskripsi gambar di sini
David
sumber
Apakah Anda perlu membuat instance kelas ini di MainActivity? Karena itu tidak mengubah apa pun untuk saya.
Tobias Mayr
1

Android menggunakan font Roboto, yang merupakan font yang terlihat sangat bagus, dengan beberapa bobot berbeda (reguler, ringan, tipis, kental) yang tampak hebat pada layar kepadatan tinggi.

Periksa tautan di bawah ini untuk memeriksa font roboto:

Cara menggunakan Roboto di tata letak xml

Kembali ke pertanyaan Anda, jika Anda ingin mengubah font untuk semua TextView / Button di aplikasi Anda , coba tambahkan kode di bawah ini ke styles.xml Anda untuk menggunakan font Roboto-light :

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    ......
    <item name="android:buttonStyle">@style/MyButton</item>
    <item name="android:textViewStyle">@style/MyTextView</item>
</style>

<style name="MyButton" parent="@style/Widget.AppCompat.Button">
    <item name="android:textAllCaps">false</item>
    <item name="android:fontFamily">sans-serif-light</item>
</style>

<style name="MyTextView" parent="@style/TextAppearance.AppCompat">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

Dan jangan lupa untuk menggunakan 'AppTheme' di AndroidManifest.xml Anda

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    ......
</application>
Pedagang lilin
sumber
0

Mungkin sesuatu yang sedikit lebih sederhana:

public class Fonts {
  public static HashSet<String,Typeface> fonts = new HashSet<>();

  public static Typeface get(Context context, String file) {
    if (! fonts.contains(file)) {
      synchronized (this) {
        Typeface typeface = Typeface.createFromAsset(context.getAssets(), name);
        fonts.put(name, typeface);
      }
    }
    return fonts.get(file);
  }
}

// Usage
Typeface myFont = Fonts.get("arial.ttf");

(Catat kode ini belum diuji, tetapi secara umum pendekatan ini harus bekerja dengan baik.)

trans
sumber