Utilizzare il carattere Roboto per i dispositivi precedenti

Vorrei utilizzare il carattere Roboto nella mia applicazione Android e assicurarsi che funziona per le versioni precedenti di Android che non hanno installato il font. So che posso farlo utilizzando Typeface.createFromAsset () e poi impostare manualmente il carattere per ciascuno dei miei TextViews / Buttons / Other-Objects. Sembra un grande dolore per farlo per each object che mostro sullo schermo però.

La mia domanda è, c'è un modo migliore per farlo? Alcune classi di supporto o un modo per impostare un carattere personalizzato in un file di tema .xml? Tutto ciò che è automatizzato sarebbe meglio che elencare manualmente each object su ciascuna schermata e cambiare il font.

  • Impostazione miniatura dell'album di Android
  • Android: come get il valore dell'attributo "listPreferredItemHeight" nel codice?
  • attività pila
  • Come faccio a get la differenza tra due date in android ?, provato each cosa e post
  • Errore durante l'avvio di un programma Android
  • Android: EventHub.removeMessages (int what = 107) non è supportto prima che sia configurato il WebViewCore
  • Grazie!

  • Approccio allo sviluppo di applicazioni mobili che supportno un'applicazione web
  • InvocationTargetException su gonfiare un xml - android
  • Eliminare lo spazio di border attorno a GridView
  • Retrofit previsto BEGIN_OBJECT ma era BEGIN_ARRAY
  • Come recuperare le informazioni sui dispositivi Bluetooth con il dispositivo di selezione Bluetooth di Android?
  • Fotocamera di qualsiasi emulatore che non funziona
  • 6 Solutions collect form web for “Utilizzare il carattere Roboto per i dispositivi precedenti”

    Recupera tutte le viste all'interno dell'attività, controlla il suo tipo e applica l'azione appropriata.

    Typeface typeface = Typeface.createFromAsset(getAssets(), "fonts/Roboto/Roboto-Regular.ttf"); for (View view : allViews) { if (view instanceof TextView) { TextView textView = (TextView) view; textView.setTypeface(typeface); } } 

    Sopra la risposta accettata è corretta, ma ho solo voluto fornire la mia implementazione qui

    La mia class di utilità:

     package com.example.utils; import android.content.Context; import android.graphics.Typeface; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class AndroidUtils { private static Typeface robotoTypeFace; public static void setRobotoFont (Context context, View view) { if (robotoTypeFace == null) { robotoTypeFace = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto/Roboto-Regular.ttf"); } setFont(view, robotoTypeFace); } private static void setFont (View view, Typeface robotoTypeFace) { if (view instanceof ViewGroup) { for (int i = 0; i < ((ViewGroup)view).getChildCount(); i++) { setFont(((ViewGroup)view).getChildAt(i), robotoTypeFace); } } else if (view instanceof TextView) { ((TextView) view).setTypeface(robotoTypeFace); } } } 

    Come usarlo, supponendo che sia un'attività:

     AndroidUtils.setRobotoFont(this, view); 

    Per impostare lo stesso font su tutti i TextView è ansible utilizzare il decorView della tua attività:

     ViewGroup godfatherView = (ViewGroup)this.getWindow().getDecorView(); AndroidUtils.setRobotoFont(this, godfatherView); 

    Se si dispone di adattatori o frammenti, non dimenticare di impostare anche il loro tipo di carattere.

    Vedi anche qui .

    Grazie a @Jitsu, @Arnaud e @Pawan M, ho fatto la mia soluzione, meglio di tutti:

     /** * Adapted from http://stackoverflow.com/a/12387343/450148 * * @author Anton Averin * @author Felipe Micaroni Lalli */ package net.alouw.alouwCheckin.util; import android.content.Context; import android.graphics.Typeface; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.EnumMap; import java.util.Map; public final class FontUtils { private FontUtils() { } private enum FontType { BOLD("fonts/Roboto/Roboto-BoldCondensed.ttf"), BOLD_ITALIC("fonts/Roboto/Roboto-BoldCondensedItalic.ttf"), NORMAL("fonts/Roboto/Roboto-Condensed.ttf"), ITALIC("fonts/Roboto/Roboto-CondensedItalic.ttf"); private final String path; FontType(String path) { this.path = path; } public String getPath() { return path; } } /* cache for loaded Roboto typefaces*/ private static Map<FontType, Typeface> typefaceCache = new EnumMap<FontType, Typeface>(FontType.class); /** * Creates Roboto typeface and puts it into cache */ private static Typeface getRobotoTypeface(Context context, FontType fontType) { String fontPath = fontType.getPath(); if (!typefaceCache.containsKey(fontType)) { typefaceCache.put(fontType, Typeface.createFromAsset(context.getAssets(), fontPath)); } return typefaceCache.get(fontType); } /** * Gets roboto typeface according to passed typeface style settings. * <p/> * Will get Roboto-Bold for Typeface.BOLD etc */ private static Typeface getRobotoTypeface(Context context, Typeface originalTypeface) { FontType robotoFontType = null; if (originalTypeface == null) { robotoFontType = FontType.NORMAL; } else { int style = originalTypeface.getStyle(); switch (style) { case Typeface.BOLD: robotoFontType = FontType.BOLD; break; case Typeface.BOLD_ITALIC: robotoFontType = FontType.BOLD_ITALIC; break; case Typeface.ITALIC: robotoFontType = FontType.ITALIC; break; case Typeface.NORMAL: robotoFontType = FontType.NORMAL; break; } } return (robotoFontType == null) ? originalTypeface : getRobotoTypeface(context, robotoFontType); } /** * Walks ViewGroups, finds TextViews and applies Typefaces taking styling in consideration * * @param context - to reach assets * @param view - root view to apply typeface to */ public static void setRobotoFont(Context context, View view) { if (view instanceof ViewGroup) { for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { setRobotoFont(context, ((ViewGroup) view).getChildAt(i)); } } else if (view instanceof TextView) { Typeface currentTypeface = ((TextView) view).getTypeface(); ((TextView) view).setTypeface(getRobotoTypeface(context, currentTypeface)); } } } 

    E l'ultima cosa nella tua attività principale onCreate:

     if (Build.VERSION.SDK_INT < 11) { ViewGroup godfatherView = (ViewGroup) this.getWindow().getDecorView(); FontUtils.setRobotoFont(this, godfatherView); } 

    E nelle mie liste con visualizzazioni personalizzate il codice sopra non funzionava, quindi wherevo fare questo:

     @Override public View getView(int position, View convertView, ViewGroup parent) { // (...) View view = // build your custom view here if (Build.VERSION.SDK_INT < 11) { FontUtils.setRobotoFont(activity, view); } return view; } 

    Ecco la mia versione migliorata di questa soluzione. Può eseguire la cache dei caratteri e tiene in considerazione le impostazioni dei parametri di TextView.textStyle. Quindi è ansible impostare text grassetto. http://anton.averin.pro/2012/09/12/how-to-use-android-roboto-font-in-honeycomb-and-earlier-versions/

    Uso un'altra soluzione. Impostazione LayoutInflater.Factory personalizzata per l'attività. Così ho pieno accesso alla vista dopo la creazione. Posso installare il carattere personalizzato per each TextView senza iterare sulla gerarchia di visualizzazione. Una cosa da fare per utilizzare il carattere personalizzato in tutta la tua applicazione è call new Font(...).install() nella tua attività di base. Vedere l'esapolo di seguito.

    Ecco la mia soluzione con il campione di utilizzo:

     import java.util.Map; import com.google.common.collect.Maps; import static com.google.common.base.Preconditions.checkNotNull; import android.R; import android.app.Activity; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Typeface; import android.support.v4.app.FragmentActivity; import android.util.AttributeSet; import android.util.Log; import android.view.InflateException; import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; /** * Provides an ability to apply custom font to all {@link TextView} and subclasss. * * To install custom font use method {@link #install(Activity)} in {@link Activity#onCreate(android.os.Bundle)} * <b>before</b> calling super.onCreate(Bundle). * * <p/>Example of usage: * <pre> * {@code * public class BaseActivity extends SherlockFragmentActivity { * * protected void onCreate(Bundle state) { * applyCustomFontForPreICS(); * super.onCreate(state); * } * * private void applyCustomFontForPreICS() { * boolean isPreICS = Build.VERSION.SDK_INT < BUILD_VERSION_CODE_ICE_CREAM_SANDWICH * if (isPreICS) { * new Font( * "font/roboto_regular.ttf", * "font/roboto_bold.ttf", * "font/roboto_italic.ttf", * "font/roboto_bold_italic.ttf" * ).install(this); * } * } * } * } * </pre> * * @author Alexey Danilov (danikula@gmail.com) */ public class Font { private static final Map<String, Typeface> FONTS = Maps.newHashMap(); private String regularFontPath; private String boldFontPath; private String italicFontPath; private String boldItalicFontPath; /** * Creates instance to be used for setting particular font. * * @param regularPath regular font assets path, must be not {@code null} * @param boldPath bold font assets path, must be not {@code null} * @param italicPath italic font assets path, must be not {@code null} * @param boldItalicPath bold and italic font assets path, must be not {@code null} */ public Font(String regularPath, String boldPath, String italicPath, String boldItalicPath) { this.regularFontPath = checkNotNull(regularPath); this.boldFontPath = checkNotNull(boldPath); this.italicFontPath = checkNotNull(italicPath); this.boldItalicFontPath = checkNotNull(boldItalicPath); } /** * Installs custom font to activity. * * @param activity an activity custom font will be installed to, must be not {@code null}. */ public void install(Activity activity) { checkNotNull(activity, "Activity must be not null!"); LayoutInflater layoutInflater = activity.getLayoutInflater(); boolean factoryIsEmpty = layoutInflater.getFactory() == null; if (!factoryIsEmpty) { throw new IllegalStateException("Impossible to use this method for this activity: layout factory is set!"); } layoutInflater.setFactory(new FontLayoutInflaterFactory()); } private Typeface getFont(int type, Context context) { switch (type) { case Typeface.NORMAL: return getFont(context, regularFontPath); case Typeface.BOLD: return getFont(context, boldFontPath); case Typeface.ITALIC: return getFont(context, italicFontPath); case Typeface.BOLD_ITALIC: return getFont(context, boldItalicFontPath); default: { throw new IllegalArgumentException("Undefined font type " + type); } } } private Typeface getFont(Context context, String path) { if (FONTS.containsKey(path)) { return FONTS.get(path); } else { Typeface typeface = makeTypeface(context, path); FONTS.put(path, typeface); return typeface; } } private Typeface makeTypeface(Context context, String path) { try { return Typeface.createFromAsset(context.getAssets(), path); } catch (Exception e) { // add user-friendly error message throw new IllegalArgumentException(String.format("Error creating font from assets path '%s'", path), e); } } private void applyFontToTextView(Context context, TextView textView, AttributeSet attrs) { int[] fontStyleAttributes = {R.attr.textStyle}; TypedArray typedArray = context.obtainStyledAttributes(attrs, fontStyleAttributes); boolean isStyleSpecified = typedArray.getIndexCount() != 0; int type = isStyleSpecified ? typedArray.getInt(0, Typeface.NORMAL) : Typeface.NORMAL; Typeface font = getFont(type, context); textView.setTypeface(font, type); } private final class FontLayoutInflaterFactory implements LayoutInflater.Factory { // to improve perfomance the package with the most usable components should be the first. private final String[] ANDROID_UI_COMPONENT_PACKAGES = { "android.widget.", "android.webkit.", "android.view." }; @Override public View onCreateView(String name, Context context, AttributeSet attrs) { try { // we install custom LayoutInflater.Factory, so FragmentActivity have no chance set own factory and // inflate tag <fragment> in method onCreateView. So call it explicitly. if ("fragment".equals(name) && context instanceof FragmentActivity) { FragmentActivity fragmentActivity = (FragmentActivity) context; return fragmentActivity.onCreateView(name, context, attrs); } View view = createView(name, attrs, LayoutInflater.from(context)); if (view == null) { // It's strange! The view is not ours neither android's. May be the package of this view // is not listed in ANDROID_UI_COMPONENT_PACKAGES. Return null for the default behavior. Log.d(LOG_TAG, "Cannot create view with name: " + name); return null; } if (view instanceof TextView) { TextView textView = (TextView) view; applyFontToTextView(context, textView, attrs); } return view; } catch (InflateException e) { Log.e(LOG_TAG, "Error inflating view", e); return null; } catch (ClassNotFoundException e) { Log.e(LOG_TAG, "Error inflating view", e); return null; } } private View createView(String name, AttributeSet attrs, LayoutInflater layoutInflater) throws ClassNotFoundException { View view = null; boolean isAndroidComponent = name.indexOf('.') == -1; if (isAndroidComponent) { // We don't know package name of the view with the given simple name. Try android ui packages listed in // ANDROID_UI_COMPONENT_PACKAGES // The same implementation is in the class PhoneLayoutInflater from internal API for (String androidPackage : ANDROID_UI_COMPONENT_PACKAGES) { try { view = layoutInflater.createView(name, androidPackage, attrs); if (view != null) { break; } } catch (ClassNotFoundException e) { // Do nothing, we will try another package } } } else { view = layoutInflater.createView(name, null, attrs); } return view; } } } 

    Nota che ha dipendenza dalla guava , ma è ansible implementare questi methods da solo.

    La migliore solluzione mai è Calligraphy

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.