ReactNativeでレスポンシブなフォントサイズを実装する

ReactNativeでアプリを作っている時、font-size(フォントサイズ)で困ったことはありませんか?

fontSizeはそのままの数字で指定すると、そのままの大きさで表示されます。つまり、「iPhoneではちょうどいいが、iPadで見ると文字が小さい!」といった問題が起こります。逆に、「Androidの小さめのスマホで見ると文字がデカすぎる」といった問題もあります。

私が実装している「LangJournal」というアプリでは、自動でサイズを調整できるようにしております。Responsiveなアプリの作り方を記載していきます。

まずは結論から

metrics.ts
import { Dimensions } from 'react-native';

const { width, height } = Dimensions.get('window');

const guidelineBaseWidth = 375;
const guidelineBaseHeight = 812;

const horizontalScale = (size) => (width / guidelineBaseWidth) * size;
const verticalScale = (size) => (height / guidelineBaseHeight) * size;
const moderateScale = (size, factor = 0.3) =>
  size + (horizontalScale(size) - size) * factor;

export { horizontalScale, verticalScale, moderateScale };

サイズを自動で調整するファイルを作成

ベースサイズの決定

まずはベースとなる横と縦のサイズを決めます。私は、横375,縦812にしております。上のソースコードの「guidelineBaseWidth」と「guidelineBaseHeight」と書かれた箇所です。

横幅をレスポンシブ対応する

「horizontalScale」は横幅を指定するときに使います。具体的には下記などです。

  • paddingLeft
  • paddingHorizontal
  • marginLeft
  • marginHorizontal

縦幅をレスポンシブ対応する

「verticalScale」は縦幅を指定するときに使います。具体的には下記などです。

  • paddingVertical
  • paddingTop
  • marginVerticcal
  • marignTop

フォントや画像などのレスポンシブ対応

horizontalScaleとverticalScaleは端末のサイズに比例して大きくなります。paddingとmarginは問題ないのですが、fontSizeや画像の場合、少し困ります。

例えば、デフォルトサイズより2倍大きい端末で開くと(iPadなど)、文字のサイズも2倍も大きくなります。一度試してもらうとわかると思うのですが、デカすぎます。端末が2倍でも、文字は2倍にはしたくないです。だからといって、同じサイズでは小さいです。

そんな時に使うのがverticalScaleです。factorの変数を調整することで、端末が大きくなってもそのまま大きくするのでなく、調整を加えます。こちらは数字を動かしながら色々試してみてください。LangJournalではfactor=0.3にしております。

moderateScaleで具体的に設定するものは下記です。

  • fontSize
  • imageのwidthとheight
  • iconのwidthとheight
  • borderRadius

スタイルを当てる

あとは、実際にスタイルを当てていきます。以下は一例です。

sample.tsx
const styles = StyleSheet.create({
  scrollView: {
    paddingBottom: verticalScale(20),
    paddingHorizontal: horizontalScale(8),
    marginHorizontal: horizontalScale(8),
    borderWidth: moderateScale(1),
    borderRadius: moderateScale(8),
    paddingTop: verticalScale(12),
    minHeight: verticalScale(176),
    justifyContent: 'space-between',
    borderColor: borderLight,
  },
  firstRow: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingBottom: verticalScale(8),
  },
  circle: {
    width: moderateScale(8),
    height: moderateScale(8),
    borderRadius: moderateScale(4),
    marginRight: horizontalScale(12),
  },
});

要注意ポイント

ヘッダー、ボトムタブで使うものに関しては、レスポンシブにしてはいけません。こちらは、注意が必要です。なぜなら、デフォルトで高さが固定だからです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です