Розмір власного чуйного розміру шрифту


92

Я хотів би запитати, як реагують рідні дескриптори або реагують на адаптивний шрифт. Наприклад, у iphone 4s у мене є fontSize: 14, тоді як у iphone 6 у мене fontSize: 18.


19
Якщо хтось шукає спосіб повністю вимкнути масштабування шрифту, використовуйтеText.defaultProps.allowFontScaling=false
CoderDave

1
@CoderDave це чудово!
Абдо

Якщо вам потрібен відносний fontSize на основі розміру екрана замість точного fontSize, ви можете спробувати npmjs.com/package/react-native-responsive-dimensions , він автоматично змінить розмір ваших шрифтів на основі розміру екрану пристрою
Дані Акаш

Відповіді:


98

Ви можете використовувати PixelRatio

наприклад:

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

Редагувати:

Інший приклад:

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

Використання:

fontSize: normalize(24)

Ви можете піти на крок далі, дозволивши використовувати розміри для всіх <Text />компонентів заздалегідь визначеним розміром.

Приклад:

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

22
де ти тут скористався своєю шкалою const?
Jan Franz Palngipang

2
Здається, це нічого не робить. міні завжди === 12
A.com

14
Чому ви віднімаєте 2 для пристроїв, що не ios?
Parth Tamane

51

Ми використовуємо прості, прямолінійні, масштабовані утиліти, які ми написали:

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

Заощаджує ваш час, роблячи багато випадків Ви можете прочитати більше про це в моєму дописі в блозі .


Редагувати: Я вважав, що може бути корисно витягти ці функції до власного пакета npm, я також включив ScaledSheetдо пакету, який є автоматично масштабованою версією StyleSheet. Ви можете знайти його тут: response-native-size-questions .


Дякую, який найкращий сценарій використовувати цей утиль? Я маю на увазі, де використовувати масштаб, verticaleScale та умерений масштаб?
Пір Шукарулла Шах

4
Я використовую умерений масштаб майже на всьому, що потребує масштабування, наприклад fontSize, поля, розмір зображення та розмір Svg (для макета я використовую flex), оскільки масштабування imo не повинно бути лінійним, але це особисті переваги. Якщо ви хочете досягти лінійного результату, використовуйте переважно масштаб і використовуйте verticalScale на таких матеріалах, як висота контейнерів.
nirsky

16

Оскільки реагуючі одиниці на даний момент недоступні в рідному для реагування, я б сказав, що найкращим варіантом було б визначити розмір екрана, а потім використати його, щоб зробити висновок про тип пристрою та умовно встановити fontSize.

Ви можете написати такий модуль, як:

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

Вам просто потрібно буде з’ясувати, яка ширина та висота за замовчуванням є для кожного пристрою. Якщо ширина та висота перевертаються, коли пристрій змінює орієнтацію, ви можете замість цього використовувати співвідношення сторін або просто з’ясувати менший із двох вимірів, щоб з’ясувати ширину.

Цей або цей модуль може допомогти вам знайти розміри пристрою або тип пристрою.


Я встановив React-native-Device, але це видає мені помилку "Не вдається вирішити модуль Dimension", коли я запускаю додаток
Sydney Loteria

Здається, вам потрібно переконатися, що ви використовуєте правильну версію RN для модуля
Ісаак Медвед

я використовую останню версію React Native :) Я думаю, що вона наразі не підтримується?
Sydney Loteria

Можливо ... Можливо, спробуйте видалити свою папку node_modules і повторноnpm install
Ісаак Медвед

6

Погляньте на бібліотеку, яку я писав: https://github.com/tachyons-css/react-native-style-tachyons

Це дозволяє вам вказати root-fontSize ( rem) під час запуску, який ви можете зробити залежним від своїх PixelRatioчи інших характеристик пристрою.

Тоді ви отримуєте стилі щодо вашого rem, не тільки fontSize, але і відступи тощо:

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

Пояснення:

  • f5завжди є вашим базовим шрифтом
  • pa2 дає вам відступ щодо основного розміру шрифту.

5

Я просто використовую співвідношення розміру екрану, що мені добре підходить.

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

Тест

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}

Чи означає це, що вам доведеться користуватися iPhone 6 Simulator, і виходячи з того, як він там виглядає, він буде добре виглядати на інших пристроях?
Вальтер Монеке

@WalterMonecke у моєму випадку так. Ви також можете адаптуватися до використання іншого симулятора як основи.
шентаой

4

adjustsFontSizeToFitі numberOfLinesпрацює для мене. Вони налаштовують довгу електронну пошту в 1 рядок.

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

10
згідно з документацією 'adjustsFontSizeToFit' стосується лише iOS
mdehghani

Це не працює для android
Саманта Вітнагадж

3

Мені вдалося подолати це, зробивши наступне.

  1. Виберіть розмір шрифту, який вам подобається, для поточного вигляду (переконайтеся, що він добре виглядає для поточного пристрою, який ви використовуєте в тренажері).

  2. import { Dimensions } from 'react-native' і визначте ширину за межами компонента так: let width = Dimensions.get('window').width;

  3. Тепер console.log (ширина) і запишіть його. Якщо ваш гарний розмір шрифту дорівнює 15, а ширина - 360, наприклад, тоді візьміть 360 і розділіть на 15 (= 24). Це буде важливим значенням, яке буде адаптуватися до різних розмірів.

    Використовуйте цей номер у своєму об’єкті стилів так: textFontSize: { fontSize = width / 24 },...

Тепер у вас є адаптивний fontSize.


привіт це справді працює? f1 = ширина / (ширина / розмір) це не може працювати?
Елронд

1
У підсумку я використав react-native-text.
Вальтер Монеке

3

Ми можемо використовувати гнучкий макет і використовувати adjustsFontSizeToFit = {true} для адаптивних розмірів шрифту. І текст буде коригуватися відповідно до розміру контейнера.

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

Але в стилях вам потрібно також розмістити шрифт, лише тоді налаштуванняFontSizeToFit буде працювати.

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

2

Нещодавно я зіткнувся з цією проблемою і в кінцевому підсумку скористався реакцією-рідним-розширеним стилем

Ви можете встановити remзначення та додаткові умови розміру залежно від розміру екрана. Відповідно до документів:

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

Чому б не використовувати PixelRatio.getPixelSizeForLayoutSize(/* size in dp */);, це так само, як pdодиниці в Android.


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

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

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

fontScaleотримати масштаб відповідно до вашого пристрою .


fontscale просто повертає 1 на віртуальному пристрої Android Emulator 4_WVGA_Nexus_S_API, яким я користуюся.
reggie3

0

Потрібно використовувати цей спосіб, я використав цей, і він працює нормально.

React-native-responsive-screen npm встановити response-native-responsive-screen --save

Так само, як у мене є пристрій 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%")

Він працює на всіх пристроях


0

Для мене спрацював дещо інший підхід: -

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

Є см Ratio Pixel як це дозволяє краще налаштувати функцію , засновану на щільності пристрою.


-3

Ви можете використовувати щось подібне.

var {висота, ширина} = Dimensions.get ('вікно'); var textFontSize = ширина * 0,03;

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

Сподіваюся, це допоможе без встановлення сторонніх бібліотек.


1
а звідки 0,03?
Девід Нореня,

це буде чуйним?
Діпак Ганачарі,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.