I have a code that sets the font for view items. I created a class Utils in which I endure all such instrumental functions.

Here is the function

 /** * Set the font to TextView **/ private void fontInit() { TextView tvWelcomeAct1 = (TextView) findViewById(R.id.tvWelcomAct1); TextView tvWelcomeAct2 = (TextView) findViewById(R.id.tvWelcomAct2); TextView tvWelcomeAct3 = (TextView) findViewById(R.id.tvWelcomAct3); TextView tvWelcomeAct4 = (TextView) findViewById(R.id.tvWelcomAct4); TextView tvWelcomeAct6 = (TextView) findViewById(R.id.tvWelcomAct6); TextView tvWelcomeAct7 = (TextView) findViewById(R.id.tvWelcomAct7); List<TextView> fontList = new ArrayList<>(); Collections.addAll(fontList, tvWelcomeAct1, tvWelcomeAct2, tvWelcomeAct3, tvWelcomeAct4, tvWelcomeAct6, tvWelcomeAct7); for (int i = 0; i < fontList.size(); i++) { UtilClass.setFont(context, fontList.get(i)); } } 

I was embarrassed by the fact that it has duplicated this function in all of Activity ...

Ideally, I would like to optimize this function so that it context and, separated by a comma, I twist everything, regardless of their number ...

something like that

 private void fontInit(context, tvWelcomeAct1, tvWelcomeAct2, tvWelcomeAct3, tvWelcomeAct4, tvWelcomeAct6, tvWelcomeAct7) { List<TextView> fontList = new ArrayList<>(); Collections.addAll(fontList, **только как их сюда передать**); for (int i = 0; i < fontList.size(); i++) { UtilClass.setFont(context, fontList.get(i)); } 

Thanks for the advice)

  • As far as I understood from the description, you will be helped by a method with variable length arguments (varargs) linkex.ru/java/varargs.php. PS As far as I can remember such things are better done through styles, or do you change in runtime? - Alexander Lomovskiy
  • No, no ... I just need to use my font ... Not necessarily in runtime. And how through the style to ask it? - Aleksey Timoshchenko

3 answers 3

If you constantly shove your font everywhere in all TextView , then why not make it a permanent attribute on TextView itself? The easiest option Create a new class and inherit it from TextView

 public class ExTextView extends TextView { public ExTextView(Context context) { super(context); } public ExTextView(Context context, AttributeSet attrs) { super(context, attrs); parseAttributes(context, attrs); } public ExTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); parseAttributes(context, attrs); } private void parseAttributes(Context context, AttributeSet attrs) { TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.ExTextView); int typeface = values.getInt(R.styleable.ExTextView_typeface, 0); setTypeface(FontsUtils.getTypeFace(context, typeface)); values.recycle(); } } 

Create attrs.xml file in values or add it if you already have one.

 <declare-styleable name="ExTextView"> <attr name="typeface" /> </declare-styleable> <attr name="typeface" format="enum"> <enum name="FONTS1" value="0" /> <enum name="FONTS2" value="1" /> <enum name="FONTS3" value="2" /> </attr> 

Well, the class for downloading the font itself

 public class FontsUtils { public final static int FONTS1 = 0; public final static int FONTS2 = 1; public final static int FONTS3 = 2; private static final Hashtable<String, Typeface> cache = new Hashtable<String, Typeface>(); public static Typeface getTypeFace(Context context, int typeFace) { synchronized (cache) { String assetPath; switch (typeFace) { case FONTS1: default: assetPath = "fonts/FONTS1.otf"; break; case FONTS2: assetPath = "fonts/FONTS2.otf"; break; case FONTS3: assetPath = "fonts/FONTS3.otf"; break; } if (!cache.containsKey(assetPath)) { try { cache.put(assetPath, Typeface.createFromAsset(context.getAssets(), assetPath)); } catch (Exception e) { Log.e("TypeFaces", "Typeface not loaded."); return null; } } return cache.get(assetPath); } } } 

Now how does it all work

In all your xml with TextView , where you need to change the background, we change them to our custom, where you.package.name. You must replace the package name of your application.

 <you.package.name.ExTextView android:layout_width="wrap_content" android:layout_height="wrap_content" /> 

If you have not explicitly indicated which font to use, the default font will be used in the default branches (see the FontsUtils class).

If you need to specify the font, use the app:typface (do not forget to add xmlns:app="http://schemas.android.com/apk/res-auto" to the root layout)

 <you.package.name.ExTextView android:layout_width="wrap_content" android:layout_height="wrap_content" app:typeface="FONTS2" /> 

If for some reason you need to add the font programmatically:

 TextView.setTypeFace(FontsUtils.getTypeFace(mContext, FontsUtils.FONTS2)); 

There will be questions to ask =) This is not a tricky way you will save yourself when adding new TextView , as the default will use the font you specified (in the example this is FONTS1 ).

  • Yes, but the task is complicated by the fact that I change the font, not only TextView , but also the other I twist too ... Then I have to create such a class for each twist ... And so I just have a method in the instrumental class in which I I give any twist in any quantity and do not bother with the content of custom classes ... But thanks for the answer! Very detailed. I'll save myself for later)) - Aleksey Timoshchenko
  • In order not to change the font of others, just use the usual TextView =) or change the code so that nothing happens by default =) - Chaynik
  • Yes, but the task is complicated by the fact that I change the font, not only with TextView, but also with other views, too ... Right here I didn’t understand what kind of case you were, but also with other ones I’ve also ... .... - Chaynik
  • This code after adding obviously does not immediately change the font for all) This code will only work for the view you specified. You can add 5 TextView and 3 ExTextView to the screen, in this case 3 ExTextView will have a non-standard font, the others will not touch it. - Chaynik
  • Although I just thought that it would probably be convenient all the same)) I actually don’t have so much twist of elements ... But then what about EditText and Button ? We need to create separate classes for them, right? - Aleksey Timoshchenko

Use varargs and foreach :

 void fontInit(Context context, TextView ... fontList ) { for (TextView textView : fontlist) UtilClass.setFont(context, textView); } 

Call the method, listing how much TextView needs after the context :

 fontInit(context, tvWelcomeAct1, tvWelcomeAct2, tvWelcomeAct3); 

    What you want will look something like this:

     private void fontInit(Context context, TextView... textViews) { for (TextView textView : textViews) { UtilClass.setFont(context, textView); } } 

    But specifically in the case of custom fonts, I would recommend you not to reinvent the wheel, but to use one of the ready-made solutions. Here is a whole category of libraries that allow using custom fonts anyway. From the most simple and convenient, I would highlight MagicViews and Calligraphy .