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)