Réagir la taille de la police native responsive

92

Je voudrais demander comment réagir la gestion native ou faire la police responsive. Par exemple, dans l'iphone 4s, j'ai la taille de la police: 14, tandis que dans l'iphone 6, j'ai la taille de la police: 18.

Sydney Loteria
la source
19
Si quelqu'un cherche un moyen de désactiver complètement la mise à l'échelle des polices, utilisezText.defaultProps.allowFontScaling=false
CoderDave
1
@CoderDave c'est génial!
Abdo
Si vous souhaitez une police relative en fonction de la taille de l'écran au lieu de la taille exacte de la police, vous pouvez essayer npmjs.com/package/react-native-responsive-dimensions , il redimensionnera automatiquement vos polices en fonction de la taille de l'écran de l'appareil
Dani Akash

Réponses:

98

Vous pouvez utiliser PixelRatio

par exemple:

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
  }
});

Éditer:

Un autre exemple:

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
  }
}

Usage:

fontSize: normalize(24)

vous pouvez aller plus loin en autorisant l'utilisation de tailles sur tous les <Text />composants par taille prédéfinie.

Exemple:

const styles = {
  mini: {
    fontSize: normalize(12),
  },
  small: {
    fontSize: normalize(15),
  },
  medium: {
    fontSize: normalize(17),
  },
  large: {
    fontSize: normalize(20),
  },
  xlarge: {
    fontSize: normalize(24),
  },
};
Chinloong
la source
22
où avez-vous utilisé votre échelle de const ici?
Jan Franz Palngipang
2
Cela ne semble rien faire. mini always === 12
A.com
14
Pourquoi soustrayez-vous 2 pour les appareils non iOS?
Parth Tamane
51

Nous utilisons des fonctions utilitaires simples et directes de mise à l'échelle que nous avons écrites:

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};

Vous fait gagner du temps à faire de nombreux ifs. Vous pouvez en savoir plus sur mon article de blog .


Edit: J'ai pensé qu'il pourrait être utile d'extraire ces fonctions dans leur propre package npm, que j'ai également inclus ScaledSheetdans le package, qui est une version automatiquement mise à l'échelle de StyleSheet. Vous pouvez le trouver ici: react-native-size-important .

Nirsky
la source
Merci, quel est le meilleur scénario pour utiliser ces utilitaires? Je veux dire où utiliser scale, verticaleScale et averageScale?
Pir Shukarullah Shah
4
J'utilise modéréScale sur presque tout ce qui nécessite une mise à l'échelle, comme la taille de la police, les marges, l'image et la taille Svg, (pour la mise en page, j'utilise flex) car la mise à l'échelle imo ne doit pas être linéaire, mais c'est une question de préférence personnelle. Si vous souhaitez obtenir un résultat linéaire, utilisez principalement l'échelle et utilisez verticalScale sur des éléments tels que la hauteur des conteneurs.
nirsky
16

Étant donné que les unités réactives ne sont pas disponibles pour le moment en natif de réaction, je dirais que votre meilleur pari serait de détecter la taille de l'écran, puis de l'utiliser pour déduire le type d'appareil et définir la taille de la police de manière conditionnelle.

Vous pouvez écrire un module comme:

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

Vous aurez juste besoin de rechercher la largeur et la hauteur par défaut de chaque appareil. Si la largeur et la hauteur sont inversées lorsque l'appareil change d'orientation, vous pourrez peut-être utiliser le rapport hauteur / largeur à la place ou simplement déterminer la plus petite des deux dimensions pour déterminer la largeur.

Ce module ou celui-ci peut vous aider à trouver les dimensions ou le type d'appareil.

Isaac Madwed
la source
J'ai installé le périphérique react-native mais cela me donne une erreur "Impossible de résoudre le module Dimension" lorsque j'exécute l'application
Sydney Loteria
On dirait que vous devez vous assurer que vous utilisez la bonne version de RN pour le module
Isaac Madwed
J'utilise la dernière version de React Native :) Je pense qu'elle n'est pas prise en charge actuellement?
Sydney Loteria
Peut-être ... Essayez peut-être de supprimer votre dossier node_modules et renpm install
Isaac Madwed
6

Jetez un œil à la bibliothèque que j'ai écrite: https://github.com/tachyons-css/react-native-style-tachyons

Il vous permet de spécifier un root-fontSize ( rem) au démarrage, que vous pouvez rendre dépendant de vos PixelRatiocaractéristiques ou d'autres caractéristiques de l'appareil.

Ensuite, vous obtenez des styles relatifs à votre rempolice, non seulement à la taille de la police, mais également aux rembourrages, etc.:

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

Expanation:

  • f5est toujours votre taille de police de base
  • pa2 vous donne un remplissage par rapport à votre taille de police de base.
Fabian Zeindl
la source
5

J'utilise simplement le rapport de la taille de l'écran, ce qui fonctionne très bien pour moi.

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));

Tester

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}
shentaoy
la source
Cela signifie-t-il que vous devez utiliser le simulateur iPhone 6 et qu'en fonction de son apparence, il aura fière allure sur d'autres appareils?
Walter Monecke
@WalterMonecke dans mon cas oui. Vous pouvez également vous adapter pour utiliser un autre simulateur comme base.
shentaoy
4

adjustsFontSizeToFitet numberOfLinestravaille pour moi. Ils ajustent les longs e-mails en 1 ligne.

<View>
  <Text
    numberOfLines={1}
    adjustsFontSizeToFit
    style={{textAlign:'center',fontSize:30}}
  >
    {this.props.email}
  </Text>
</View>
Gundam Meister
la source
10
selon la documentation 'ajustsFontSizeToFit' s'applique uniquement à iOS
mdehghani
Cela ne fonctionne pas pour Android
Samantha Withanage
3

J'ai réussi à surmonter cela en procédant comme suit.

  1. Choisissez la taille de police que vous aimez pour la vue actuelle que vous avez (assurez-vous qu'elle convient à l'appareil actuel que vous utilisez dans le simulateur).

  2. import { Dimensions } from 'react-native' et définissez la largeur à l'extérieur du composant comme ceci: let width = Dimensions.get('window').width;

  3. Maintenant console.log (largeur) et notez-le. Si votre bonne taille de police est de 15 et votre largeur de 360 ​​par exemple, prenez 360 et divisez par 15 (= 24). Ce sera la valeur importante qui va s'ajuster aux différentes tailles.

    Utilisez ce numéro dans votre objet styles comme ceci: textFontSize: { fontSize = width / 24 },...

Vous avez maintenant une police responsive.

Walter Monecke
la source
hey ça marche vraiment? f1 = largeur / (largeur / taille) cela ne peut pas fonctionner?
Elrond
1
J'ai fini par utiliser react-native-text.
Walter Monecke
3

Nous pouvons utiliser la mise en page flexible et utiliser adjustsFontSizeToFit = {true} pour les tailles de police réactives. Et le texte s'ajusterait en fonction de la taille du conteneur.

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

Mais dans les styles, vous devez également mettre une taille de police, alors seulement ajusteraFontSizeToFit fonctionnera.

    valueField: {
    flex: 3,
    fontSize: 48,
    marginBottom: 5,
    color: '#00A398',
},
Payel Dutta
la source
2

J'ai récemment rencontré ce problème et j'ai fini par utiliser la feuille de style react-native-extended-style

Vous pouvez définir votre remvaleur et des conditions de taille supplémentaires en fonction de la taille de l'écran. Selon les documents:

// 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
});
colakollektiv
la source
2

Pourquoi ne pas utiliser PixelRatio.getPixelSizeForLayoutSize(/* size in dp */);, c'est exactement la même chose que les pdunités sous Android.

Ahmed Kamal
la source
2
import { Dimensions } from 'react-native';

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

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

fontScaleobtenez l'échelle selon votre appareil .

Paras Korat
la source
fontscale renvoie juste 1 sur le périphérique virtuel Android Emulator 4_WVGA_Nexus_S_API que j'utilise.
reggie3
0

Besoin d'utiliser de cette façon, j'ai utilisé celui-ci et cela fonctionne très bien.

react-native-responsive-screen npm installer react-native-responsive-screen --save

Tout comme j'ai un appareil 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%")

Cela fonctionne pour tous les appareils

Tushar Kumawat
la source
0

Une approche légèrement différente a fonctionné pour moi: -

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
};

Reportez-vous au rapport de pixels car cela vous permet de mieux configurer la fonction en fonction de la densité de l'appareil.

Arpan Sharma
la source
-3

Vous pouvez utiliser quelque chose comme ça.

var {hauteur, largeur} = Dimensions.get ('fenêtre'); var textFontSize = largeur * 0,03;

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

J'espère que cela vous aidera sans installer de bibliothèques tierces.

Guna Sekhar
la source
1
et d'où vient 0,03?
David Noreña
va-t-il être réactif?
Deepak Ganachari