DEV Community

Ajmal Hasan
Ajmal Hasan

Posted on • Edited on

4 3

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

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)