React Native: Different Styles Applied on Orientation Change

React Native: Different styles applied on orientation change

Finally, I've been able to do so. Don't know the performance issues it can carry, but they should not be a problem since it's only called on resizing or orientation change.

I've made a global controller where I have a function which receives the component (the container, the view) and adds an event listener to it:

const getScreenInfo = () => {
const dim = Dimensions.get('window');
return dim;
}

const bindScreenDimensionsUpdate = (component) => {
Dimensions.addEventListener('change', () => {
try{
component.setState({
orientation: isPortrait() ? 'portrait' : 'landscape',
screenWidth: getScreenInfo().width,
screenHeight: getScreenInfo().height
});
}catch(e){
// Fail silently
}
});
}

With this, I force to rerender the component when there's a change on orientation, or on window resizing.

Then, on every component constructor:

import ScreenMetrics from './globalFunctionContainer';

export default class UserList extends Component {
constructor(props){
super(props);

this.state = {};

ScreenMetrics.bindScreenDimensionsUpdate(this);
}
}

This way, it gets rerendered everytime there's a window resize or an orientation change.

You should note, however, that this must be applied to every component which we want to listen to orientation changes, since if the parent container is updated but the state (or props) of the children do not update, they won't be rerendered, so it can be a performance kill if we have a big children tree listening to it.

Hope it helps someone!

React Native Flexbox adjustment for landscape orientation

1- You can use useWindowDimensions hook, which calculates width & hight automatically when we switch between landscape and portrait mode.

const {width, height} = useWindowDimensions();

2- Then, you can set a boolean variable to detect whether you're in landscape or not

const isLandscapeMode = width > height? true : false;

3- Now, you can switch between styles depending on isLandscapeMode variable

<View style={{ width: isLandscapeMode? 400 : 300, you can add any other styling}}>

if you don't prefer inline styles, you can also do this

<View style={isLandscapeMode? styles.landscapeStyle : styles.portraitStyle}>

React Native How to get orientation of device

When you add the listener, you can also do a manual call to get the initial orientation:

  const [orientation, setOrientation] = useState('LANDSCAPE');

const determineAndSetOrientation = () => {
let width = Dimensions.get('window').width;
let height = Dimensions.get('window').height;

if (width < height) {
setOrientation('PORTRAIT');
} else {
setOrientation('LANDSCAPE');
}
}

useEffect(() => {

determineAndSetOrientation();
Dimensions.addEventListener('change', determineAndSetOrientation);

return () => {
Dimensions.removeEventListener('change', determineAndSetOrientation)
}
}, []);

Also probably a good idea to remove the event listener (see the return statement).

How to style for both orientations

I would suggest using flex-box, which is built to handle not only this - but also screens with varying sizes.

Read up on it here: https://facebook.github.io/react-native/docs/flexbox.html

You can still use margins to move your design around, but flexing your components will lead to it working across multiple screen widths and heights.

Take a portrait screen for example, and placing a square in the top-middle with flex. If you were to rotate the screen, flex would have the dot still in the top middle of the now horiztonal-rectangle, and without, it would be in the middle of the first half of the screen ( What you might be experiencing ).



Related Topics



Leave a reply



Submit