Expoでカスタムフォントのweightを動的に切り替える方法

ReactNative

こんにちは。趣味グラマのNobuです。

Expoでフォントのweightを設定画面から動的に切り替えるアプリを作っているのですが、カスタムフォントを使った時に、weightを動的に切り替えるにはどうすれば良いのか分からず、試行錯誤の末にたどり着いた方法を紹介します。

先に言っておくと、バッドノウハウだと思います(笑)

まずはカスタムフォントのロード

カスタムフォントのロードは、Expoのドキュメントを参考にそのまま実装すればOKです。

https://docs.expo.io/versions/latest/guides/using-custom-fonts/
export default class HomeScreen extends React.Component<Props, State> {

  constructor(props: Props) {
    super(props);
    this.state = {
      fontLoaded: false
    }
  }

  async componentDidMount() {
    await Font.loadAsync({
      'open_sans-300': require('../../../assets/fonts/OpenSans-Light.ttf'),
      'open_sans-400': require('../../../assets/fonts/OpenSans-Regular.ttf'),
      'open_sans-600': require('../../../assets/fonts/OpenSans-Semibold.ttf'),
      'open_sans-700': require('../../../assets/fonts/OpenSans-Bold.ttf'),
      'open_sans-800': require('../../../assets/fonts/OpenSans-ExtraBold.ttf'),
    });

    this.setState({fontLoaded: true});
  }

  render() {
    return this.state.fontLoaded ? <HomeCompoent /> : <></>
  }
}

この時、ロード時の名前にweightの数字を設定しているのが試行錯誤の跡になります。

カスタムフォントを使う

今回はReduxを使用しており、画面でweightの設定を変更すると、storeの値が変わって再レンダリングされます。
その画面のテキストを以下のようにすると、動的にカスタムフォントのweightが変わります。

render() {
  return <Text style={this._text_style()}>ほげほげ</Text>
}

_text_style = () => {
  return StyleSheet.create({
    text: {
      fontFamily: `open_sans-${this.props.setting.text_weight}`
    }
  }).text
}

厳密には「fontWeight」というプロパティがあるので、weightを変えているとは言えないのかもしれませんが、weightが違うフォントファイルを同一のfontFamily名で設定する方法が分からず、あれこれ試した結果、このやり方になりました。

まとめ

趣味グラマは動く物を作るのが第一という事で、ある程度調べても正式なやり方が見つからない場合は、こういうやり方で逃れる事が結構あったりします。
お客様へ納品するとか、チーム開発をやっている訳でもなく、個人開発の良いところ(?)なのかもしれません(笑)

コメント

タイトルとURLをコピーしました