Skip to content

Conversation

@fabioh8010
Copy link
Collaborator

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:

  1. 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.
  2. For each entry in the font family map:
    1. Create a new XML Font file or edit an existing one, replacing already defined entries and style / weight duplicates.
    2. Copy the font files to res/font/ folder and normalize their names.
    3. Add ReactFontManager's import to MainApplication.java file if it isn't declared yet.
    4. Add a method call inside onCreate() to load the custom font on Android.

During font assets cleaning process, here is the following logic:

  1. For each deleted font file, locate the corresponding one in res/font folder that needs to be deleted.
  2. Create a font family map, where each entry is a different font family with its corresponding font files.
  3. For each entry in the font family map:
    1. Remove the font entries in the corresponding font family XML file.
    2. If the XML file is empty, remove the file and the method call in MainApplication.java.
    3. If there is no usages of ReactFontManager in MainApplication.java, remove the import as well.

@fabioh8010 fabioh8010 merged commit 827b957 into master Nov 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants