DEV Community

Ajmal Hasan
Ajmal Hasan

Posted on • Edited on

React Native Responsive UI

1)

import { Dimensions, StatusBar } from 'react-native'; const { width, height } = Dimensions.get('window'); const guidelineBaseWidth = 375; const guidelineBaseHeight = 812; const scale = size => (width / guidelineBaseWidth) * size; const verticalScale = size => (height / guidelineBaseHeight) * size; const moderateScale = (size, factor = 0.5) => size + (scale(size) - size) * factor; const moderateScaleVertical = (size, factor = 0.5) => size + (verticalScale(size) - size) * factor; const textScale = percent => { const screenHeight = Dimensions.get('window').height; //calculate absolute ratio for bigger screens 18.5:9 requiring smaller scaling const ratio = Dimensions.get('window').height / Dimensions.get('window').width; //Guideline sizes are based on standard ~5″ screen mobile device const deviceHeight = 375 ? screenHeight * (ratio > 1.8 ? 0.126 : 0.15) //Set guideline depending on absolute ratio : Platform.OS === 'android' ? screenHeight - StatusBar.currentHeight : screenHeight; const heightPercent = (percent * deviceHeight) / 100; return Math.round(heightPercent); }; export { scale, verticalScale, textScale, moderateScale, moderateScaleVertical,width,height }; 
Enter fullscreen mode Exit fullscreen mode

2)

import { useEffect, useState } from 'react'; import { Dimensions, PixelRatio, Platform } from 'react-native'; const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT, } = Dimensions.get('window'); //FONT SCALING - provide the pixel as: //Usage: nf(16) const scale = SCREEN_HEIGHT / 667; const normalizeFont = (size) => Math.round(PixelRatio.roundToNearestPixel(size * scale)) //DYNAMIC DIMENSION AS PER PERCENTAGE: //Usage: wp(5), hp(20) const widthPercentageToDP = widthPercent => { // Convert string input to decimal number const elemWidth = parseFloat(widthPercent); return PixelRatio.roundToNearestPixel(SCREEN_WIDTH * elemWidth / 100); }; const heightPercentageToDP = heightPercent => { // Convert string input to decimal number const elemHeight = parseFloat(heightPercent); return PixelRatio.roundToNearestPixel(SCREEN_HEIGHT * elemHeight / 100); }; //DYNAMIC DIMENSION AS PER PIXELS: //Usage: wpx(141), hpx(220) const widthFromPixel = (widthPx, w = 375) => { const scale = SCREEN_WIDTH / w; const newSize = widthPx * scale return newSize }; const heightFromPixel = (heightPx, h = 667) => { const scale = SCREEN_HEIGHT / h; const newSize = heightPx * scale return newSize }; export { normalizeFont as nf, widthPercentageToDP as wp, heightPercentageToDP as hp, widthFromPixel as wpx, heightFromPixel as hpx, }; USAGE: import { hp, wp, hpx, wpx, nf, Fonts } from '../../constants/constants' /** * A React Hook which updates when the orientation changes * @returns whether the user is in 'PORTRAIT' or 'LANDSCAPE' */ const isPortrait = () => { const dimMode = Dimensions.get('screen'); return dimMode.height >= dimMode.width; }; export const useOrientation = () => { // State to hold the connection status const [orientation, setOrientation] = useState( isPortrait() ? true : false, ); const [height, setHeight] = useState( isPortrait() ? 667 : 375, ); const [width, setWidth] = useState( isPortrait() ? 375 : 667, ); const [fontPixel, setFontPixel] = useState( Dimensions.get('screen').width < 425 ? 1 : 1.5 ); useEffect(() => { const callback = () => { setOrientation(isPortrait() ? true : false) setHeight(isPortrait() ? 667 : 375) setWidth(isPortrait() ? 375 : 667) setFontPixel(Dimensions.get('screen').width < 425 ? 1 : 1.5) }; Dimensions.addEventListener('change', callback); return () => { Dimensions.removeEventListener('change', callback); }; }, []); return { orientation, height, width, fontPixel }; } export const useOrientationHeight = (h) => { const screenHeight = Dimensions.get('window').height const screenWidth = Dimensions.get('window').width if (isPortrait()) { return (h / 667) * screenHeight } else { return (h / 375) * screenWidth } } export const useOrientationWidth = (w) => { const screenHeight = Dimensions.get('window').height const screenWidth = Dimensions.get('window').width if (isPortrait()) { return (w / 375) * screenWidth } else { return (w / 667) * screenHeight } } // USAGE: // const orientation = useOrientation(); returns-> true or false // vertical calculation ==> "orientation ? oh(50) : ow(30)" // horizontal calculation ==> "orientation ? ow(50) : oh(30)" 
Enter fullscreen mode Exit fullscreen mode

Example

Top comments (0)