How to design screens in react native compatible for all devices
Asked Answered
C

2

5

I am trying to design this design react-native. This is what I have coded for this but this is not what I want. This works on one screen only, if I change screen size then things are not working.

This looks like absolute layout. What changes should I make to make it in such a way so that it will work on all screen sizes.

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from "react";
import {
  AppRegistry,
  Image,
  View,
  Text,
  Button,
  StyleSheet
} from "react-native";

class SplashScreen extends Component {
  render() {
    console.disableYellowBox = true;
    return (
      <View style={styles.container}>
        <Image
          source={require("./img/talk_people.png")}
          style={{ width: 300, height: 300 }}
        />
        <Text style={{ fontSize: 22, textAlign: "center", marginTop: 30 }}>
          Never forget to stay in touch with the people that matter to you.
        </Text>
        <View style={{ marginTop: 60, width: 240 }}>
          <Button title="CONTINUE" color="#FE434C" />
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: "#FFFFFF",
    margin: 50,
    alignItems: "center",
    flex: 1,
    flexDirection: "column"
  }
});

AppRegistry.registerComponent("Scheduled", () => SplashScreen);

Expected State:

enter image description here

Current State:

Nexus 4 - 768x1280

enter image description here

Nexus 6P - 1440x2560 enter image description here

Conspectus answered 14/4, 2017 at 16:53 Comment(0)
S
10

The quick answer is to use flex within your outer container, such that you have, say:

<View style={{flex: 1}}>
    <View style={{flex: 2}}>
       <.../>//Image
    </View>
    <View style={{flex: 1}}>
       <.../>//Text
    </View>
    <View style={{flex: 1}}>
       <.../>//Button
    </View>
</View>

which will divide the container into quarters and give the top half of the screen to the image and the other two quarters to the text and button; you can use padding and margins with these as you like, and use any ratio you want.

What further needs to be considered, though, is screen pixel density, which can really wreak havoc with display sizes. I've found it handy to have an outside

import React from 'react';
import { PixelRatio } from 'react-native';
let pixelRatio = PixelRatio.get();

export const normalize = (size) => {
  switch (true){
    case (pixelRatio < 1.4):
        return size * 0.8;
        break;
    case (pixelRatio < 2.4):
        return size * 1.15;
        break;
    case (pixelRatio < 3.4):
        return size * 1.35;
        break;
    default:
        return size * 1.5;
  }
}

export const normalizeFont = (size) => {
  if (pixelRatio < 1.4){
    return Math.sqrt((height*height)+(width*width))*(size/175);
  }
  return Math.sqrt((height*height)+(width*width))*(size/100);
}

module which I use as

import { normalize, normalizeFont } from '../config/pixelRatio';
const {width, height} = require('Dimensions').get('window');

...and for an image, say:

<Image source={ require('../images/my_image.png') } style={ { width: normalize(height*.2), height: normalize(height*.2) } } />

and a font:

button_text: {
    fontSize: normalizeFont(configs.LETTER_SIZE * .7),
    color: '#ffffff'
},

Hope this helps!

Edit: The module above has worked for me for devices I've deployed to, but it should be expanded to allow for pixelRatio values of from 1 to 4 with some decimal (e.g. 1.5) values in there, too. There's a good chart at this link that I'm working from to try to finish this out, but so far what has worked best is as I've posted above.

Soper answered 14/4, 2017 at 18:23 Comment(1)
Are there any packages handling this? Seems like a pretty common task for RN devs.Vicinity
M
1

Another great way of creating dynamic layout is by using the Dimensions, Personally I hate flex (couldn't understand it at times) Using Dimensions You could get the screen width and height. After which you could divide the result and assign them to top level components

import React, { Component } from "react";
import {
  View,
  StyleSheet,
  Dimensions
} from "react-native";

const styles = StyleSheet.create({
container: {
   backgroundColor: "#FFFFFF",
   height: Dimensions.get('window').height,
   width: Dimensions.get('window').width, 
   //height:Dimensions.get('window').height*0.5// 50% of the screen
   margin: 50,
   alignItems: "center",
   flex: 1,
   flexDirection: "column"
 }
});

Also adding to this, came across this library that supports media queries, if you are comfy with css styles just give it a try

Minorite answered 16/4, 2017 at 19:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.