React Native Responsive Font Size


95

Gostaria de perguntar como reage a lidar com nativos ou como fazer a fonte responsiva. Por exemplo, no iphone 4s, tenho fontSize: 14, enquanto no iphone 6, tenho fontSize: 18.


19
Se alguém estiver procurando uma maneira de desabilitar completamente o dimensionamento da fonte, useText.defaultProps.allowFontScaling=false
CoderDave 01 de

1
@CoderDave isso é brilhante!
Abdo

1
Caso você queira fontSize relativo com base no tamanho da tela em vez do fontSize exato, você pode tentar npmjs.com/package/react-native-responsive-dimensions , ele redimensionará automaticamente suas fontes com base no tamanho da tela do dispositivo
Dani Akash

Respostas:


100

Você pode usar PixelRatio

por exemplo:

var React = require('react-native');

var {StyleSheet, PixelRatio} = React;

var FONT_BACK_LABEL   = 18;

if (PixelRatio.get() <= 2) {
  FONT_BACK_LABEL = 14;
}

var styles = StyleSheet.create({
  label: {
    fontSize: FONT_BACK_LABEL
  }
});

Editar:

Outro exemplo:

import { Dimensions, Platform, PixelRatio } from 'react-native';

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

// based on iphone 5s's scale
const scale = SCREEN_WIDTH / 320;

export function normalize(size) {
  const newSize = size * scale 
  if (Platform.OS === 'ios') {
    return Math.round(PixelRatio.roundToNearestPixel(newSize))
  } else {
    return Math.round(PixelRatio.roundToNearestPixel(newSize)) - 2
  }
}

Uso:

fontSize: normalize(24)

você pode ir um passo além, permitindo que tamanhos sejam usados ​​em todos os <Text />componentes por tamanhos predefinidos.

Exemplo:

const styles = {
  mini: {
    fontSize: normalize(12),
  },
  small: {
    fontSize: normalize(15),
  },
  medium: {
    fontSize: normalize(17),
  },
  large: {
    fontSize: normalize(20),
  },
  xlarge: {
    fontSize: normalize(24),
  },
};

22
onde você usou sua escala const aqui?
Jan Franz Palngipang

2
Isso não parece fazer nada. mini sempre === 12
A.com

16
Por que você está subtraindo 2 para dispositivos não ios?
Parth Tamane

@chinloong Obrigado, isso funciona bem, mas por que -2 no Android?
colakollektiv

52

Usamos funções de utilitários de escalonamento simples e diretas que escrevemos:

import { Dimensions } from 'react-native';
const { width, height } = Dimensions.get('window');

//Guideline sizes are based on standard ~5" screen mobile device
const guidelineBaseWidth = 350;
const guidelineBaseHeight = 680;

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

export {scale, verticalScale, moderateScale};

Economiza algum tempo fazendo muitos ifs. Você pode ler mais sobre isso no meu blog .


Edit: Achei que seria útil extrair essas funções para seu próprio pacote npm, também incluído ScaledSheetno pacote, que é uma versão dimensionada automaticamente do StyleSheet. Você pode encontrá-lo aqui: react-native-size-matter .


Obrigado, qual é o melhor cenário para usar esses utilitários? Quero dizer, onde usar scale, verticaleScale e moderScale?
Pir Shukarullah Shah

4
Eu uso o moderScale em quase tudo que precisa de escala, como fontSize, margens, imagem e tamanho de Svg, (para layout eu uso flex) porque a escala imo não deve ser linear, mas isso é uma questão de preferência pessoal. Se quiser obter um resultado linear, use principalmente a escala e use verticalScale em coisas como alturas de contêineres.
nirsky

16

Como as unidades responsivas não estão disponíveis no react-native no momento, eu diria que sua melhor aposta seria detectar o tamanho da tela e então usar isso para inferir o tipo de dispositivo e definir o fontSize condicionalmente.

Você pode escrever um módulo como:

function fontSizer (screenWidth) {
  if(screenWidth > 400){
    return 18;
  }else if(screenWidth > 250){
    return 14;
  }else { 
    return 12;
  }
}

Você só precisa verificar qual é a largura e a altura padrão de cada dispositivo. Se a largura e a altura forem invertidas quando o dispositivo mudar de orientação, você poderá usar a proporção de aspecto ou apenas descobrir a menor das duas dimensões para descobrir a largura.

Este módulo ou este pode ajudá-lo a encontrar dimensões ou tipo de dispositivo.


Eu instalei o dispositivo react-native, mas me deu um erro de "Não foi possível resolver o módulo Dimension" quando executo o aplicativo
Sydney Loteria

Parece que você precisa ter certeza de que está usando a versão correta do RN para o módulo
Isaac Madwed

estou usando a versão mais recente do React Native :) Acho que não é compatível atualmente?
Sydney Loteria

Possivelmente ... Talvez tente remover sua pasta node_modules e renpm install
Isaac Madwed

6

Dê uma olhada na biblioteca que escrevi: https://github.com/tachyons-css/react-native-style-tachyons

Ele permite que você especifique um root-fontSize ( rem) no início, que você pode tornar dependente dePixelRatio ou de outras características do dispositivo.

Então você obtém estilos relativos ao seu rem, não apenas fontSize, mas também preenchimentos, etc.

<Text style={[s.f5, s.pa2, s.tc]}>
     Something
</Text>

Expansão:

  • f5é sempre o seu tamanho de fonte base
  • pa2 fornece padding relativo ao seu tamanho de fonte base.

5

Eu simplesmente uso a proporção do tamanho da tela, o que funciona bem para mim.

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

// Use iPhone6 as base size which is 375 x 667
const baseWidth = 375;
const baseHeight = 667;

const scaleWidth = width / baseWidth;
const scaleHeight = height / baseHeight;
const scale = Math.min(scaleWidth, scaleHeight);

export const scaledSize =
    (size) => Math.ceil((size * scale));

Teste

const size = {
    small: scaledSize(25),
    oneThird: scaledSize(125),
    fullScreen: scaledSize(375),
};

console.log(size);

// iPhone 5s
{small: 22, oneThird: 107, fullScreen: 320}
// iPhone 6s
{small: 25, oneThird: 125, fullScreen: 375}
// iPhone 6s Plus
{small: 28, oneThird: 138, fullScreen: 414}

Isso significa que você precisa usar o simulador do iPhone 6 e, com base em sua aparência, ficará bem em outros dispositivos?
Walter Monecke

@WalterMonecke no meu caso sim. Você também pode se adaptar para usar outro simulador como base.
shentaoy

4

Consegui superar isso fazendo o seguinte.

  1. Escolha o tamanho da fonte que você deseja para a visualização atual que você tem (certifique-se de que parece bom para o dispositivo atual que você está usando no simulador).

  2. import { Dimensions } from 'react-native' e definir a largura fora do componente como: let width = Dimensions.get('window').width;

  3. Agora console.log (largura) e anote. Se o tamanho da sua fonte de boa aparência for 15 e a largura 360, por exemplo, pegue 360 ​​e divida por 15 (= 24). Este será o valor importante que se ajustará aos diferentes tamanhos.

    Use este número em seu objeto de estilos assim: textFontSize: { fontSize = width / 24 },...

Agora você tem um fontSize responsivo.


ei isso realmente funciona? f1 = largura / (largura / tamanho) isso não pode estar funcionando?
Elrond,

1
Acabei usando react-native-text.
Walter Monecke de

4

adjustsFontSizeToFite numberOfLinesfunciona para mim. Eles ajustam e-mails longos em 1 linha.

<View>
  <Text
    numberOfLines={1}
    adjustsFontSizeToFit
    style={{textAlign:'center',fontSize:30}}
  >
    {this.props.email}
  </Text>
</View>

10
de acordo com a documentação 'ajustaFontSizeToFit' aplica-se apenas ao iOS
mdehghani

3

Podemos usar layout flexível e usar adjustsFontSizeToFit = {true} para tamanhos de fonte responsivos. E o texto se ajustaria de acordo com o tamanho do contêiner.

     <Text
    adjustsFontSizeToFit
    style={styles.valueField}>{value}
    </Text>

Mas em estilos você também precisa colocar um tamanho de fonte, só então o ajuste de FontSizeToFit funcionará.

    valueField: {
    flex: 3,
    fontSize: 48,
    marginBottom: 5,
    color: '#00A398',
},

2

Recentemente, encontrei este problema e acabei usando react-native-extended-stylesheet

Você pode definir o remvalor e as condições adicionais de tamanho com base no tamanho da tela. De acordo com os documentos:

// component
const styles = EStyleSheet.create({
  text: {
    fontSize: '1.5rem',
    marginHorizontal: '2rem'
  }
});
// app entry
let {height, width} = Dimensions.get('window');
EStyleSheet.build({
  $rem: width > 340 ? 18 : 16
});

2

Por que não usar PixelRatio.getPixelSizeForLayoutSize(/* size in dp */);, é igual às pdunidades do Android.


2
import { Dimensions } from 'react-native';

const { width, fontScale } = Dimensions.get("window");

const styles = StyleSheet.create({
    fontSize: idleFontSize / fontScale,
});

fontScaleobtenha escala de acordo com seu dispositivo .


fontscale apenas retorna 1 no dispositivo virtual Android Emulator 4_WVGA_Nexus_S_API que estou usando.
reggie3

0

Preciso usar desta forma Eu usei este e está funcionando bem.

react -native-responsive-screen npm install react-native-responsive-screen --save

Assim como eu tenho um dispositivo 1080x1920

The vertical number we calculate from height **hp**
height:200
200/1920*100 = 10.41% - height:hp("10.41%")


The Horizontal number we calculate from width **wp**
width:200
200/1080*100 = 18.51% - Width:wp("18.51%")

Está funcionando para todos os dispositivos


0

Uma abordagem ligeiramente diferente funcionou para mim: -

const normalize = (size: number): number => {
  const scale = screenWidth / 320;
  const newSize = size * scale;
  let calculatedSize = Math.round(PixelRatio.roundToNearestPixel(newSize))

  if (PixelRatio.get() < 3)
    return calculatedSize - 0.5
  return calculatedSize
};

Consulte Pixel Ratio, pois isso permite que você configure melhor a função com base na densidade do dispositivo.


-3

Você pode usar algo assim.

var {altura, largura} = Dimensions.get ('janela'); var textFontSize = largura * 0,03;

inputText: {
    color : TEXT_COLOR_PRIMARY,
    width: '80%',
    fontSize: textFontSize
}

Espero que isso ajude sem instalar nenhuma biblioteca de terceiros.


1
e de onde veio 0,03?
David Noreña

vai ser responsivo?
Deepak Ganachari,
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.