NativeBaseの’Roboto_medium’フォントをプリロードする方法


NativeBaseのText APIは、テキストを表示する場合に使うのだが、Androidの表示においては、事前にRoboto_mediumフォントを読み込ませなければならない。

さもないと、次のエラー内容が発生する。

fontFamily “Roboto_medium” is not a system font and has not been loaded through Font.loadAsync.

Roboto_mediumがシステムフォントじゃないから、Font.loadAsync()で読み込むように、とのことだ。

iPhoneのfontFamilyはsystemなのだが、AndroidはRoboto_mediumが指定されている。当該フォントを読み込まなければならないが、fontFamily宣言前にロード完了しておきたいところだ。

このエントリーでは、「fontFamily “Roboto_medium” is not a system font and has not been loaded through Font.loadAsync.」の回避方法を紹介したい。

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isReady: false
    };
  }
  async _loadResourcesAsync() {
    const loadedFonts = await Font.loadAsync({
      Roboto: require('./node_modules/native-base/Fonts/Roboto.ttf'),
      Roboto_medium: require('./node_modules/native-base/Fonts/Roboto_medium.ttf'),
    });
    return Promise.all([loadedFonts]);
  }
  render() {
    if (!this.state.isReady) {
      return <AppLoading
        startAsync={this._loadResourcesAsync}
        onFinish={() => this.setState({ isReady: true })} />;
    }
    return (
      <Container>
        <Content>
          <Text>この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。</Text>
        </Content>
      </Container>
    );
  }
}

まずrender直後にif (!this.state.isReady) {...}でisReadyステートを判定する。trueでなければAppLoadingコンポーネントがマウントされる。

フォントは、Font.loadAsync()メソッドで読み込み、その内容をPromise.all([])に追加してreturnする。

AppLoadingコンポーネントのstartAsync propsに与えられたPromiseオブジェクトを解決する。

AppLoadingコンポーネントのonFinish propsが、startAsync propsの解決をトリガーにしてthis.setState({ isReady: true })を実施する。同時にAppLoadingコンポーネントをアンマウントする。

再renderされる。

if (!this.state.isReady) {...}を通過する。

目当てのJSXが表示される。

まとめ

‘Roboto_medium’フォントをプリロードする方法の紹介だった。「fontFamily “Roboto_medium” is not a system font and has not been loaded through Font.loadAsync.」のようなエラーに遭遇したら試してもらいたい。

エラーの有無に関わらず、プリロードすること自体は、エクスペリエンス向上が見込める。積極的にトライしてみてほしい。

このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。


Leave a Reply

Your email address will not be published. Required fields are marked *