Im trying to set my header height so its responsive for tablets and smartphones. I've have tried using flex column:
const headerStyle = {
paddingHorizontal: theme.metrics.mainPadding,
paddingTop: 0,
paddingBottom: 0,
backgroundColor: theme.colors.blue,
flex: 0.5,
flexDirection: 'column',
};
However, the header looks ok on a tablet but too tall on a smartphone.
What is the best way to set dimensions for different devices?
EDIT:
I have this function:
export function em(value: number) {
return unit * value;
}
And I am now using it in my stylesheet:
headerHeight: em(6),
headerImageWidth: em(3),
headerImageHeight: em(3),
headerLogoHeight: em(6),
headerLogoWidth: em(20),
The image looks ok on tablet, but now on smartphone its too small. If i understand correctly, I need to use dimensions.width to set an appropriate unit value in my function?
Smartphone
Tablet
I can think of two ways
Using flex
<View style={{flex:1}}>
<View style={{flex:0.2}}>
<Text>Header</Text>
</View>
<View style={{flex:0.8}} />
</View>
You have mentioned using flex, but not working. I am not sure how exactly as if you are using it like above, size should be relative to screen size.
Using Dimensions
How about using the Dimensions module. It can be used to get the width and height of the window and you can set height based on that
import {
Dimensions
} from 'react-native';
const winWidth = Dimensions.get('window').width;
const winHeight = Dimensions.get('window').height;
header = {
height: winHeight * 0.2 // 20%
}
Then use width and height to set the height of the header (ex. percentage-based)
Related
I want to have a carousel that each item is a zoomable image, the carousel should be all over the screen so I use Portal for that. To support zoom I use ImageZoom component from react-native-image-pan-zoom, and the carousel is from react-native-reanimated-carousel, in the following way:
<Portal>
<Carousel
loop
windowSize={1}
width={SCREEN_WIDTH}
height={SCREEN_HEIGHT}
data={images}
style={{
flex: 1,
backgroundColor: "black",
}}
defaultIndex={imageIndexToDisplay}
onSnapToItem={handleImageChange}
renderItem={({ item: { url, width, height } }) => (
<ImageZoom
cropWidth={SCREEN_WIDTH}
cropHeight={SCREEN_HEIGHT}
imageWidth={width}
imageHeight={height}
enableSwipeDown
onSwipeDown={handleClose}
onClick={handlePress}
useNativeDriver
>
<Image
imageSource={url}
defaultImage={defaultImage}
imageStyle={{ height, width }}
/>
</ImageZoom>
)}
/>
</Portal>
What happens is that the carousel barely let me scroll left or right since it seems like the ImageZoom responds first to the scrolls. I tried to set onStartShouldSetPanResponder={() => false} on the ImageView which solves the Carousel scrolling but doesn't let me use the ImageZoom to zoom since it appears like the Carousel now responds first to gestures.
I would like to know if there is any way to make them both work together.
Thanks ahead!
I'm building a component in ReactJs that shows some text over a image in a page. This text is configured in a configuration manager app that is created with ReactJs too.
I am using vw (viewport width) as units, beacuse this component needs to be responsive. Using those units the size text is always fitted right. And if I resize the windows the text is in the same place.
My problem is the configuration manager where I configure the text that is going to appear, because I am making a preview of this component inside of modal window.
I need to locate correctly and exactly where the text will appear like if it were the orignal render. It needs to be like a minature of the real component.
I am using vw too, but it doesn't work. It appears in another site of the container and also when I resize the window the text moves too.
I tried to use vmin units, but they did not work too.
I need the container to take the reference as if it were the browser window so that the viewport width units use the same measurements like a preview.
Or if you have any other idea to do this.
This is a reduced part of the code in ReactJS. Also the state is charged with test data for understanding the problem
import React, { Component } from 'react';
import '../styles/main.scss';
class PreviewEditor extends Component {
constructor(props) {
super(props);
this.state = {
text: {
text: '',
fontSize: 2,
position: {
vertical: {
key: 'top',
value: 20
},
horizontal: {
key: 'right',
value: 10
}
}
}
}
}
render() {
let object = this.props;
return (
<div>
<div className='container-body'>
<div>
<div className="container-preview">
<img src={object.url}></img>
<div className="conteiner-text" style={{
[this.state.text.position.vertical.key]: this.state.text.position.vertical.value + "vw",
[this.state.text.position.horizontal.key]: this.state.text.position.horizontal.value + "vw",
fontSize: this.state.text.fontSize + "vw",
}}>
<label>{this.state.text.text}</label>
</div>
</div>
</div>
<div className="row">
............ TODO
</div>
</div>
</div>
);
}
}
export default PreviewEditor
And this the css part
.container-preview {
background-color: #2dc5c5;
width: 100%;
position: relative;
}
.container-preview > img{
max-width: 100%;
}
.conteiner-text{
display: inline-block;
position: absolute;
}
vw stands for viewport width, it aims at always setting size relative to the current viewport, no matter the container. If you just want size relative to container width you should rather user percentage sizes.
So, in your case, you could set each container width differently (using vw for the actual container and pixels for the preview, for example) and all their content sizes in percentage to always have the same ratio at different scales.
Our app includes a screen where there is a large circle in the background which changes position. It's mostly absolute positioning using this sort of style. The circle changes to use the right style and animates into the new position underneath some tutorial text.
const { height, width } = Dimensions.get('screen')
const circleRadius = isIphoneX() ? height * 0.55 : height * 0.60
export const styles = StyleSheet.create({
circleMassiveLeft: {
position: 'absolute',
backgroundColor: primary,
width: circleRadius * 2,
height: circleRadius * 2,
borderRadius: circleRadius,
left: -circleRadius + width - 50,
top: -circleRadius + height / 2
},
circleMassiveRight: {
position: 'absolute',
backgroundColor: primary,
width: circleRadius * 2,
height: circleRadius * 2,
borderRadius: circleRadius,
left: -circleRadius + 50,
top: -circleRadius + height / 2
}
})
This has been working great to display the circle in the correct position across multiple display sizes. Since it needs to be so precisely positioned, using absolute positioning seems to be a better solution than flex in this case. Our challenge is that when changing the system settings in Android to display size small, the circle becomes smaller. Of course, that makes sense in a way, but this particular element looks pretty awful because of the layout of the rest of the screen when it's resized to be smaller. Elements that used to be on top of it are now poking out! Is there a way to make sure that this element displays at the same size regardless of Android system display size settings? Poking around the docs, there doesn't seem to be a basic setting for this.
Try to use www.npmjs.com/package/react-native-responsive-dimensions
read this
In the article they using: react-native-size-matters
I'm very new to React-Native and Javascript and have been trying to learn. I'm trying to set an image's width to the screen size divided by 10. I set up a constructor and a state with the screen width and height, but am unable to use the state to set the width or height of my image.
constructor(props) {
super(props);
const { width, height } = Dimensions.get("window")
this.state = {
width,
height
}
}
If I do this...
<Image source={require('./my-icon.png')} style={{width: {this.state.width}, height: 40}}/>
It gives me an error saying that 'this' is a reserved word.
I fixed it. I guess I made a dumb mistake. I removed the brackets and it worked.
<Image source={require('./my-icon.png')} style={{width: this.state.width/10, height: 40}}/>
I am trying to add rows of two images to a ScrollView in Titanium. I am having a problem in that only one row gets shown.
My Alloy code looks like this:
<Alloy>
<Window class='container' statusBarStyle='Ti.UI.iPhone.StatusBar.LIGHT_CONTENT'>
// Make ios status bar correct color
<View height='20' top='0' left='0' backgroundColor='#01B6AC'></View>
<View id = 'savedContents' layout='vertical' top='20'>
</View>
<Require type='view' src='bottomBar' id='bottomBar'/>
<Widget id="fa" src="com.mattmcfarland.fontawesome"/>
</Window>
</Alloy>
My Controller code looks like this:
var scrollView = Ti.UI.createScrollView({
contentWidth: 'auto',
contentHeight: 'height',
showVerticalScrollIndicator: false,
showHorizontalScrollIndicator: false,
width: '100%',
height: 400,
top: 0
});
for (i=0; i < venueDetails.length; i++) {
row = Ti.UI.createView({
width:'100%',
height:150,
layout:'composite'
});
image1 = Ti.UI.createImageView({
image:'http://www.outnow.io/assets/img/small511by309/'+venueDetails[i]["image1"],
width:'50%',
height:150,
left:0,
top:0
});
row.add(image1);
if (i+1 < venueDetails.length) {
image2 = Ti.UI.createImageView({
image:'http://www.outnow.io/assets/img/small511by309/'+venueDetails[i+1]["image1"],
width:'50%',
height:150,
left:'50%',
top:0
});
row.add(image2);
}
//$.savedContents.add(row);
scrollView.add(row);
}
$.savedContents.add(scrollView);
If I add the row views directly to the $.savedContents view (as per the commented out line in the code above) I see all of the rows correctly (two images per row). If I do this via a createScrollView I only get one row of images. I need to use the scrollView to make the images scrollable.
Anyone know what I am doing wrong?
By default the layout property has a value composite. So the scrollView has the composite layout, so you need to specify the positioning properties or "pins" (top, bottom, left, right and center) for that view (row). In your code you only specified the width and height, so all views will be centered in the parent view (ScrollView).
According to Titanium.UI.View-property-layout Reference:
composite (or absolute). Default layout. A child view is positioned
based on its positioning properties or "pins" (top, bottom, left,
right and center). If no positioning properties are specified, the
child is centered.