React Native Responsive Font Size

91

Chciałbym zapytać, jak reaguje natywna obsługa lub responsywna czcionka. Na przykład w iPhonie 4s mam fontSize: 14, podczas gdy w iPhonie 6 mam fontSize: 18.

Sydney Loteria
źródło
19
Jeśli ktoś szuka sposobu na całkowite wyłączenie skalowania czcionek, użyjText.defaultProps.allowFontScaling=false
CoderDave
1
@CoderDave, to jest genialne!
Abdo
Jeśli chcesz mieć względny rozmiar czcionki w oparciu o rozmiar ekranu zamiast dokładnego rozmiaru czcionki, możesz spróbować npmjs.com/package/react-native-responsive-dimensions , automatycznie zmieni rozmiar czcionek na podstawie ekranu urządzenia Rozmiar
Dani Akash

Odpowiedzi:

97

Możesz użyć PixelRatio

na przykład:

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

Edytować:

Inny przykład:

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

Stosowanie:

fontSize: normalize(24)

możesz pójść o krok dalej, zezwalając na użycie rozmiarów na każdym <Text />komponencie według wstępnie zdefiniowanego rozmiaru.

Przykład:

const styles = {
  mini: {
    fontSize: normalize(12),
  },
  small: {
    fontSize: normalize(15),
  },
  medium: {
    fontSize: normalize(17),
  },
  large: {
    fontSize: normalize(20),
  },
  xlarge: {
    fontSize: normalize(24),
  },
};
chinloong
źródło
22
gdzie wykorzystałeś tutaj swoją skalę const?
Jan Franz Palngipang
2
Wydaje się, że to nic nie daje. mini zawsze === 12
A.com
14
Dlaczego odejmujesz 2 w przypadku urządzeń innych niż iOS?
Parth Tamane
51

Używamy prostych, nieskomplikowanych funkcji narzędzi skalujących, które napisaliśmy:

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

Oszczędza trochę czasu, wykonując wiele „ifów”. Możesz przeczytać więcej na ten temat na moim blogu .


Edycja: Pomyślałem, że pomocne może być wyodrębnienie tych funkcji do ich własnego pakietu npm, który również dołączyłem ScaledSheetdo pakietu, który jest automatycznie skalowaną wersją programu StyleSheet. Możesz go znaleźć tutaj: reaguj-natywny-rozmiar-sprawy .

nirsky
źródło
Dzięki, jaki jest najlepszy scenariusz użycia tych narzędzi? Mam na myśli, gdzie użyć skali, verticaleScale i średniScale?
Pir Shukarullah Shah
4
Używam umiarkowanej skali do prawie wszystkiego, co wymaga skalowania, jak fontSize, marginesy, obraz i rozmiar Svg (dla układu używam flex), ponieważ skalowanie imo nie powinno być liniowe, ale to kwestia osobistych preferencji. Jeśli chcesz uzyskać liniowy wynik, używaj głównie skali i używaj verticalScale na rzeczach takich jak wysokość kontenerów.
nirsky
16

Ponieważ jednostki responsywne nie są obecnie dostępne w natywnym reagowaniu, powiedziałbym, że najlepszym rozwiązaniem byłoby wykrycie rozmiaru ekranu, a następnie użycie go do wywnioskowania typu urządzenia i warunkowego ustawienia rozmiaru czcionki.

Możesz napisać moduł taki jak:

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

Musisz tylko sprawdzić, jaka jest domyślna szerokość i wysokość dla każdego urządzenia. Jeśli szerokość i wysokość są odwracane, gdy urządzenie zmienia orientację, możesz zamiast tego użyć współczynnika proporcji lub po prostu obliczyć mniejszy z dwóch wymiarów, aby obliczyć szerokość.

Ten lub ten moduł może pomóc Ci znaleźć wymiary lub typ urządzenia.

Isaac Madwed
źródło
Zainstalowałem urządzenie typu react-native-device, ale po uruchomieniu aplikacji pojawia się błąd „Nie można rozwiązać wymiaru modułu”
Sydney Loteria,
Wygląda na to, że musisz się upewnić, że używasz odpowiedniej wersji RN dla modułu
Isaac Madwed
Używam najnowszej wersji React Native :) Myślę, że obecnie nie jest ona obsługiwana?
Sydney Loteria
Ewentualnie ... Może spróbuj usunąć folder node_modules i ponownienpm install
Isaac Madwed
6

Zajrzyj do biblioteki, którą napisałem: https://github.com/tachyons-css/react-native-style-tachyons

Pozwala na określenie root-fontSize ( rem) przy starcie, który można uzależnić od swojej PixelRatiolub innych cech urządzenia.

Następnie otrzymujesz style w stosunku do twojego rem, nie tylko fontSize, ale także dopełnienia itp .:

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

Ekspansja:

  • f5jest zawsze twoim podstawowym rozmiarem czcionki
  • pa2 daje dopełnienie względem twojego podstawowego rozmiaru czcionki.
Fabian Zeindl
źródło
5

Po prostu używam współczynnika rozmiaru ekranu, który dla mnie działa dobrze.

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

Test

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
źródło
Czy to oznacza, że ​​trzeba korzystać z symulatora iPhone'a 6 i na podstawie tego, jak tam wygląda, będzie dobrze wyglądał na innych urządzeniach?
Walter Monecke,
@WalterMonecke w moim przypadku tak. Możesz również dostosować się do używania innego symulatora jako podstawy.
shentaoy
4

adjustsFontSizeToFiti numberOfLinespracuje dla mnie. Dopasowują długi e-mail do jednej linii.

<View>
  <Text
    numberOfLines={1}
    adjustsFontSizeToFit
    style={{textAlign:'center',fontSize:30}}
  >
    {this.props.email}
  </Text>
</View>
Gundam Meister
źródło
10
zgodnie z dokumentacją 'adjustsFontSizeToFit' dotyczy tylko iOS
mdehghani
To nie działa dla Androida
Samantha Withanage
3

Udało mi się to pokonać, wykonując następujące czynności.

  1. Wybierz rozmiar czcionki, który chcesz dla bieżącego widoku, który masz (upewnij się, że wygląda dobrze dla bieżącego urządzenia, którego używasz w symulatorze).

  2. import { Dimensions } from 'react-native' i zdefiniuj szerokość poza komponentem w następujący sposób: let width = Dimensions.get('window').width;

  3. Teraz console.log (width) i zapisz go. Jeśli dobrze wyglądająca czcionka ma rozmiar 15, a szerokość to na przykład 360, weź 360 i podziel przez 15 (= 24). To będzie ważna wartość, która będzie dostosowywana do różnych rozmiarów.

    Użyj tego numeru w swoim obiekcie stylów w następujący sposób: textFontSize: { fontSize = width / 24 },...

Teraz masz responsywny rozmiar czcionki.

Walter Monecke
źródło
hej, czy to naprawdę działa? f1 = szerokość / (szerokość / rozmiar) to nie może działać?
Elrond,
1
Skończyło się na używaniu react-native-text.
Walter Monecke
3

Możemy użyć układu elastycznego i dostosowaćsFontSizeToFit = {true} do responsywnych rozmiarów czcionek, a tekst dostosuje się do rozmiaru kontenera.

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

Ale w stylach musisz również ustawić rozmiar czcionki, tylko wtedy będzie działać dopasowaniesFontSizeToFit.

    valueField: {
    flex: 3,
    fontSize: 48,
    marginBottom: 5,
    color: '#00A398',
},
Payel Dutta
źródło
2

Niedawno natknąłem się na ten problem i skończyło się na użyciu arkusza stylów React-Native-Extended

Możesz ustawić remwartość i dodatkowe warunki rozmiaru w oparciu o rozmiar ekranu. Zgodnie z dokumentacją:

// 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
źródło
2

Dlaczego nie używać PixelRatio.getPixelSizeForLayoutSize(/* size in dp */);, to jest to samo, co pdjednostki w systemie Android.

Ahmed Kamal
źródło
2
import { Dimensions } from 'react-native';

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

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

fontScaleuzyskaj skalę zgodnie z urządzeniem .

Paras Korat
źródło
fontscale właśnie zwraca 1 na używanym urządzeniu wirtualnym Android Emulator 4_WVGA_Nexus_S_API.
reggie3
0

Muszę używać w ten sposób. Użyłem tego i działa dobrze.

reaguj-natywny-responsywny-ekran npm zainstaluj reaguj-natywny-responsywny-ekran - zapisz

Tak jak mam urządzenie 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%")

Działa na wszystkich urządzeniach

Tushar Kumawat
źródło
0

U mnie zadziałało nieco inne podejście: -

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

Skorzystaj z opcji Pixel Ratio, ponieważ pozwala to lepiej skonfigurować funkcję w oparciu o gęstość urządzenia.

Arpan Sharma
źródło
-3

Możesz użyć czegoś takiego.

var {wysokość, szerokość} = Dimensions.get ('okno'); var textFontSize = width * 0,03;

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

Mam nadzieję, że to pomoże bez instalowania bibliotek innych firm.

Guna Sekhar
źródło
1
i skąd pochodzi 0,03?
David Noreña,
czy będzie responsywny?
Deepak Ganachari