alirezafc
alirezafc

Reputation: 162

How to handle responsive layout in React Native

I'm using the react-native-dimension library for making my UI responsive as follows:

const{width,height} = Dimensions.get('window');

and in my style.js file :

imageBackgroundLandscape:{
    width:height,
    height:width

},
imageBackgroundPortrait:{
    width:width,
    height:height
}

The problem is that when I rotate the screen, the width and height variables have got previous values! For example in the portrait mode my variables are:

width : 800
height: 1280

and when I rotate the screen my variables are:

width : 800 // previous value
height: 1280 // previous value

In addition, I use the react-native-orientation to determine the mode of the screen. I want to know how can I change the values of them (width, height) automatically when I rotate the device, or are there any other libraries for this?

Thanks in advance.

Upvotes: 4

Views: 22645

Answers (6)

Ehsan Sarshar
Ehsan Sarshar

Reputation: 3211

You can use these steps to make your UI responsive.

  1: use percentage whenever it's possible
  2: use the power of flexbox to make your UI grow and shrink
  3: use Dimension API

Upvotes: 3

Rajesh N
Rajesh N

Reputation: 6673

I am using react-native-responsive-screen. it is working also with orientation change

USAGE

import {
  widthPercentageToDP as wp,
  heightPercentageToDP as hp,
  listenOrientationChange as lor,
  removeOrientationListener as rol
} from 'react-native-responsive-screen';

class Login extends Component {
  componentDidMount() {
    lor(this);
  }

  componentWillUnmount() {
    rol();
  }

  render() {
    const styles = StyleSheet.create({
      container: { flex: 1 },
      textWrapper: {
        height: hp('70%'),
        width: wp('80%')
      },
      myText: { fontSize: hp('5%') }
    });

    return (
      <View style={styles.container}>
        <View style={styles.textWrapper}>
          <Text style={styles.myText}>Login</Text>
        </View>
      </View>
    );
  }
}

export default Login;

Upvotes: 1

Anubhav Gupta
Anubhav Gupta

Reputation: 1216

Firstly:

You are facing that issue is because you forgot to call const{width,height} = Dimensions.get('window'); again when the orientation has changed. In order to get the latest value of width and height after the orientation change you would have to call the Dimensions.get('window') function again and get width and height from it's output.

Secondly:

Instead of using multiple libraries, you can just use one library(react-native-styleman), that lets you handle this type of stuff very easily:

Here is how the code would look like using react-native-styleman.

import { withStyles } from 'react-native-styleman';
const styles = () => ({       
    container: {
        // your common styles here for container node.
        flex: 1,
        // lets write a media query to change background color automatically based on the device's orientation 
        '@media': [
          {
             orientation: 'landscape', // for landscape
             styles: {                 // apply following styles
                // these styles would be applied when the device is in landscape 
                // mode.
                 backgroundColor: 'green'
                 //.... more landscape related styles here...
             }
          },
          {
             orientation: 'portrait', // for portrait
             styles: {                // apply folllowing styles
                // these styles would be applied when the device is in portrait 
                // mode.
                 backgroundColor: 'red'
                 //.... more protrait related styles here...
             }
          }
        ]
    }
});

let MainComponent = ({ styles })=>(
    <View style={styles.container}>
        <Text> Hello World </Text>
    </View>
);

// now, lets wire up things together.
MainComponent = withStyles(styles)(MainComponent);

export {
  MainComponent
};

Upvotes: 1

Mohammad Harith
Mohammad Harith

Reputation: 619

I usually used Flexbox to arrange the layout for my components. It helps them to be responsive. Maybe you could give a try too.

Layout with Flexbox

Upvotes: 4

Suraj Malviya
Suraj Malviya

Reputation: 3773

I usually handle the height, width confusion with the following code:

//Dimensions.js
import {Dimensions} from 'react-native';
const {height, width} = Dimensions.get('window');

const actualDimensions =  {
  height:  (height<width) ? width : height,
  width: (width>height) ? height : width
};

export default actualDimensions;

Instead of requiring the height and width from Dimensions, use the actualDimensions and for managing the orientation gracefully you should give a try to this library as well.

The Dimensions are loaded before the JS bundle gets loaded into the app so it is recommended to fetch the height, width dynamically for every render You can read this here

Upvotes: 7

AmerllicA
AmerllicA

Reputation: 32512

Actually, you do right but half of the task. you got the width and height from Dimensions and it is right, but how react-native understand your orientation changes?

First, your code should understand the change of orientation, then you set a call-back function to change the state of your application for implementing new width and height.

Awfully, I don't know the react-native can understand a change of orientation with its built-in functions or not. So I'm using this library to understand orientation changes and then I use setState to re-render the codes.

Absolutely, I put the width and height inside state of the component.

If you wanna lock the orientation change, use this library.

Upvotes: 1

Related Questions