In order to use custom fonts in an android app there seem to be two approaches:
Classic way: place TTF or OTF files in the /assets/fonts directory and then build a Typeface with Typeface.createFromAsset(getAssets(), "fonts/custom.ttf").
Natively since API 26, or with AppCompat since API 16: create an XML font family by placing lowercased TTF/OTF files in res/font folder and then reference them directly in XML layouts with android:fontFamily="#font/custom", or access them programatically with ResourcesCompat.getFont(this, R.font.custom).
What are the key differences to keep in mind between font resources and assets?
Specifically, are they rendered in the same way, and is any of them faster or more efficient in terms of performance?
Can it be assumed that font resources are only suitable for fonts that come pre-packaged in the APK, while font assets are more flexible since you can create a Typeface from an arbitrary file inside or outside the APK?
Update:
After a bit of experimentation it looks like font resources are the only way to set custom fonts in AppWidget TextViews without having to manually paint them as bitmaps but that requires the device to actually run API 26 (using the Support Library does not help in this specific case).
Specifically, are they rendered in the same way, and is any of them faster or more efficient in terms of performance?
ResourcesCompat.getFont works like this:
Check in-memory cache if we already resolved a font resource ID to Typeface. If we have a hit, we're done.
Copy the resource to a disk file.
Create Typeface from the file using Typerface.createFromFile and cache it.
That's true for fonts bundled in the APK. I won't go into how downloadable fonts work. You can explore that in the docs or in the source.
Both approaches work the same. They create a Typeface object from a source.
One key difference: If you're directly using Typeface API, you're responsible for caching. You don't want to load the same font multiple times because each Typeface instance takes up loads of memory.
Historically, I was using this code from Calligraphy to take care of caching when loading typefaces from assets.
After a bit of experimentation it looks like font resources are the only way to set custom fonts in AppWidget TextViews [...]
Looks like you're right. Notifications and widgets (anything that uses RemoteViews) can only use natively available resources and attributes on views.
See also: How to use a custom typeface in a widget?
Related
I'm trying to create Persian pdf files in my android application using www.itextpdf.com but I get java.io.IOException arial.ttf not found as file or resource. Here is the code with the problem.
BaseFont font = BaseFont.createFont("arial.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
this code is fine in eclipse(java project not android) but wont work in Android studio. I don't know how to address the ttf file. Any help would be appreciated.
This is obvious: Android does not have Arial font.
You have to ship the appropriate font for your script (Persian) along with your application and read the font from resources/assets/etc.
See also How to retrieve a list of available/installed fonts in android?.
UPD:
Once you have your file in assets, grab an AssetManager via getAssets() and use it to read the bytes from the font. This answer might be useful.
Afterwards you are free to create your font like this:
BaseFont.createFont("arial.ttf", BaseFont.IDENTITY_H, true, false, bytes, null);
Meanwhile, I strongly encourage you to read thoroughly on the licensing of the fonts that are shipped with Windows to determine whether you are able to copy-paste Arial font into your application and then use it like this (I doubt so).
Take a look here:
Attribute
customAttrs:fontType="free_mono"
The TextView
<com.seamusdawkins.fontcustom.CustomTextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="#string/str_text_default"
android:textSize="30dp"
customAttrs:fontType="free_mono"
android:gravity="center"/>
See this link for more information.
I'm trying to use custom fonts in an android wear app, but until now no success. I can't find any specific documentation about using custom typefaces for android wear and tried to apply the same method for normal android apps.
I created a assets folder in my project by using android studio and created a folder inside it named fonts. I placed the font file in this folder.
In the onCreate() method i added following line to load font as a typeface.
mTypeface = Typeface.createFromAsset(getBaseContext().getAssets(), "fonts/fontawesome-webfont.ttf");
And finally created a Paint object and set the typeface
paint.setTypeface(mTypeface);
But canvas.drawText() doesn't draw desired fonts.
My question is, is it even possible to use custom typefaces in an android wear application? If yes, how?
Thanks.
Maybe you forgot to pass the Paint parameter to the drawText method like this:
canvas.drawText("Sample text in bold",0,0, paint);
Notice the fourth parameter, if you don't specify which paint will draw the text, it won't draw like that.
Hope I help someone.
I've used custom fonts multitudes of time for Android Wear watch faces, but I don't see why it should be any different for creating standalone applications. Have you tried other fonts?
I'm building a wear app for a client at the moment, but I'm not at the stage where I need to change the typeface yet. I can try this for you however and see if I experience same results.
I am using arial.ttf in my project. In genymotion emulator,in some mobile devices my text view is look good. But in Sony Xperia tablet 4.1.1 i have a text rendering problem. Text looking very bad. What should i do?
<TextView
android:id="#+id/yazi1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/Ret"
android:textColor="#color/siyah"
android:textColorHint="#color/siyah"
android:textSize="#dimen/font14" />
Typeface tfArial = Typeface.createFromAsset(getAssets(), "arial_tur2.ttf")
screenshot http://hizliresim.com/ynJjWk
Use OTF instead of TTF. That can be your problem. I was in this situation and changing the file with OTF solved my problem.
OTF is more likely to be a “better” font, as it supports more advanced typesetting features (smallcaps, alternates, ligatures and so on actually inside the font rather than in fiddly separate expert set fonts). It can also contain either spline (TTF-style) or Bezier (PostScript Type 1-style) curves, so hopefully you're getting the shapes the font was originally designed in and not a potentially-poorer-quality conversion.
On the other hand, if you're downloading free fonts from shovelware sites, you're unlikely to get any of that. Indeed, you may simple be getting a TTF font renamed to OTF.
I am using the following line of code to change the font type in android application :L
Typeface font = Typeface.createFromAsset(this.getAssets(), "fonts/Abumohammed.ttf");
textView.setTypeface(font);
I am sure that Abumohammed.ttf is in assets/fonts folder .. but the font don't change and don't has any effect on the textview !!
Android does not support every font file. When it fails, it tends to fail silently, showing the default font instead. I have no idea what Android does not like about some of them.
I would find some font that definitely works, such as this one, and try it to make sure that the rest of your code is OK. If indeed you determine that the font file does not work, AFAIK you have no choice but to find some other font.
I was annoyed enough by this that I thought I'd share some results of my digging. I tried a few font files that ended up using the fallback font. To 'fix' some of these files, I simply had to open the file in FontForge, then File->Generate Font and re-save as TTF. This allowed some that were not showing to draw properly.
Others required moving the glyphs from the Microsoft area (U+F030) to U+0030 range.
I haven't educated myself on what 'Generate Font' actually does. But, now that I know HOW to fix it, I can at least start to figure out why it isn't working. I suspect this can only be fixed in the AOSP tree however.
I'm developing an application which has some assets bundled with it - they are mostly web pages with associated graphics, css etc which I'll display in a custom WebView. I'm trying to work out how to serve up different assets to different devices without massive duplication.
I'd like to replicate the res folder, but for assets. For example:
assets/html/page1.html references assets/html/example_pic.png but I want to serve up a different example_pic.png depending on screen density or screen size.
Ideally I'd like to have something like assets_hdpi/html/example_pic.png and assets_mdpi/html/example_pic.png
Is there an elegant way of achieving this? Can I somehow utilise the /res/ folder management to the same end result by putting the example_pic.png in to /res/drawable_hdpi etc and then somehow pointing the webpage to the drawable?
A possible workaround:
Prepare a 'subpath' named string for the different resolutions you want to address, e.g.:
res/values-hdpi/subpath.xml: <string name="subpath">hdpi</string>
res/values-ldpi/subpath.xml: <string name="subpath">ldpi</string>
Prepare corresponding subpaths in your asset folder, e.g.:
assets/hdpi, assets/ldpi and store your assets there.
Finally, use getResources.getString(R.string.subpath) to get the best asset subpath.
String AssetPath= "file:///android_asset/"+getResources.getString(R.string.subpath)+"/";
myWebView.loadPage(AssetPath+"index.html");