react-native-asset
react-native-asset copied to clipboard
Improve Android fonts linking process
This PR aims to improve the whole Android fonts linking process.
Problem
Currently, during Android linking, font assets are copied to Android asset's folder and then can be used in the application. The problem is that in RN Android has a different logic to manage fonts related to iOS, requiring the developer to rely on the font file's name to be able to use the font properly in the application.
To give an example, let's say I added Lato font to my project and linked the files in both Android and iOS platforms. These are the Lato font files:
- Lato-Black.ttf
- Lato-BlackItalic.ttf
- Lato-Bold.ttf
- Lato-BoldItalic.ttf
- Lato-Italic.ttf
- Lato-Light.ttf
- Lato-LightItalic.ttf
- Lato-Regular.ttf
- Lato-Thin.ttf
- Lato-ThinItalic.ttf
For iOS, I can simply use a combination of fontFamily
, fontWeight
and fontStyle
styles to select the desired font:
<Text style={{ fontFamily: 'Lato', fontWeight: '700', fontStyle: 'italic' }}>Lato 700 Italic</Text>
For Android, this approach won't work and you have to rely on the font's name in order to select the desired font.
<Text style={{ fontFamily: 'Lato-BoldItalic' }}>Lato 700 Italic</Text>
Developers end up having to use different approaches in order to custom fonts work properly for both platforms.
Solution
This PR solves the stated problem by changing the Android linking process to do the steps described in this guide automatically. In Android, fonts are now going to be managed by using XML Fonts to handle all font's variants.
During font assets copying process, here is the following logic:
- Read all font assets and create a font family map, where each entry is a different font family with its corresponding font files and its styles / weights.
- For each entry in the font family map:
- Create a new XML Font file or edit an existing one, replacing already defined entries and style / weight duplicates.
- Copy the font files to
res/font/
folder and normalize their names. - Add
ReactFontManager
's import toMainApplication.java
file if it isn't declared yet. - Add a method call inside
onCreate()
to load the custom font on Android.
During font assets cleaning process, here is the following logic:
- For each deleted font file, locate the corresponding one in
res/font
folder that needs to be deleted. - Create a font family map, where each entry is a different font family with its corresponding font files.
- For each entry in the font family map:
- Remove the font entries in the corresponding font family XML file.
- If the XML file is empty, remove the file and the method call in
MainApplication.java
. - If there is no usages of
ReactFontManager
inMainApplication.java
, remove the import as well.
@unimonkiez Thanks for your review! About the migration, even if I implement it won't be 100% seamless as it would require changes in the application as well, specifically how the developer use fontFamily
, fontStyle
and fontWeight
. One thing we could do is display a message in the terminal explaining about the migration made and the necessary steps to update application's code as well, maybe even with a link to a doc file or something. WDYT?
@unimonkiez Thanks for your review! About the migration, even if I implement it won't be 100% seamless as it would require changes in the application as well, specifically how the developer use
fontFamily
,fontStyle
andfontWeight
. One thing we could do is display a message in the terminal explaining about the migration made and the necessary steps to update application's code as well, maybe even with a link to a doc file or something. WDYT?
Sounds excellent !
@unimonkiez I updated the PR with the following changes:
- Addressed the requested changes
- Implemented a migration for the new Android font linking logic. Tested with edge cases as well e.g. migrating while adding/removing fonts
- Added documentation and fixed some typos
- Improved font italic detection logic to cover an edge case
Changes: https://github.com/unimonkiez/react-native-asset/pull/52/files/5952050efc5ab27f4592a85ce5ba843ce56d65c0..a902630a1313c3a0c6116937e0a2f56cf9f0215c
Hi @unimonkiez , did you have a chance to take a look at the latest changes on this PR? Thanks!
Hi @unimonkiez, just bringing this PR to your attention again, I appreciate any feedback or action you could take. Thanks!
@unimonkiez thanks for your reviews of this pull request so far. We'd love to help push this feature forward in whatever way we can 🙂
Thanks for your work @fabioh8010 and @unimonkiez It works really well.
If anyone wants to use it now:
- Uninstall any previous version
npm uninstall -g react-native-asset
npm uninstall -D react-native-asset
- Install version from fabioh8010
npm i -D github:fabioh8010/react-native-asset#feature/android-font-family-improvement