NativeBase card fitting/scaling the image within the card - react-native

First: I have looked at this, but didn't find what I was looking for.
I wanna create something like this
But I have some problems with the resizing of an large image.. I found out that I can fix the pixels by doing inline style and using height and width. But I want it to look good on an iPad as well... What to do?
Here is my code
import React, { Component } from 'react';
import { Image } from 'react-native';
import { List, Card, CardItem, Thumbnail, Text, Button, Icon } from 'native-base';
class ListEquipment extends Component {
constructor() {
super();
}
render () {
return (
<List style={{padding: 5}}
dataArray={this.props.items}
renderRow={(item) =>
<Card >
<CardItem>
<Thumbnail source={require('../img/Robot-96.png')} />
<Text>Card</Text>
<Text note>Bonus Info</Text>
</CardItem>
<CardItem cardBody>
<Image source={require('../img/micscrope.jpg')} />
<Text>
Information goes here..
</Text>
<Button >
<Icon name="ios-beer" />
<Text>Cheers</Text>
</Button>
</CardItem>
</Card>
}
/>
)
}
};
export default ListEquipment;

Are you looking to size the images based on the size of the device?
If so, you can use:
import SCREEN_IMPORT from 'Dimensions'
const SCREEN_WIDTH = SCREEN_IMPORT.get('window').width,
const SCREEN_HEIGHT = SCREEN_IMPORT.get('window').height,
You will then be able to set the width/height inline as a percentage of SCREEN_HEIGHT and SCREEN_WIDTH.
Additionally you will want to consider the pixelRatio, it is recommended to store varying sizes of an image so that downsizing/upscaling will not effect image quality.
var image = getImage({
width: PixelRatio.getPixelSizeForLayoutSize(200),
height: PixelRatio.getPixelSizeForLayoutSize(100),
});
<Image source={image} style={{width: 200, height: 100}} />
Where getImage will return the nearest sized image for the device screen/pixel ratio.

First thing I would do is to wrap the Image on a View. Then, set a height that matches the aspect ratio of the image and then use resizeMode: 'contain'.
Anyway, this is the closest I could get:
<View style={{backgroundColor: 'green', margin: 10, borderColor: 'yellow', borderWidth: 2}}>
<View style={{backgroundColor: 'green', padding: 10, borderBottomColor: 'yellow', borderBottomWidth: 2}}>
<Text style={{fontSize: 20}}>Header</Text>
</View>
<View style={{backgroundColor: 'red'}}>
<View style={{alignItems: 'center', height: 150}}>
<Image source={require('./test.png')} style={{flex: 1, resizeMode: 'contain'}}/>
</View>
<View style={{backgroundColor: 'violet'}}>
<Text style={{color: 'blue'}}>Description</Text>
</View>
</View>
</View>
With a 500x300(px) image this generates:
By using an image with the correct aspect ratio it looks way better:

Related

justifyContent: 'center' not working React Native

i want to center the image but it seems the justifyContent: 'center' property is not working as i want
I'm learning about flexbox in react-native
Also, I want to ask how can my code run on many different devices without changing the layout. I code on iphone 14 but when I switch to ipad or iphone se, the layout is changed and almost not as expected.
picture
my code
import React from 'react';
import {Dimensions, Image, Text, View} from 'react-native';
import {colors, sizes, spacing} from '../../constants/config';
import Icon from '../../utils/Icon';
const cardWidth = sizes.width / 3;
const cardHeight = 120;
const CartItem = ({list}) => {
return (
<View style={{flex: 1}}>
{list.map((item, index) => {
return (
<View style={{height: '20%'}} key={index}>
<View
style={{
marginLeft: spacing.l,
marginRight: spacing.l,
backgroundColor: 'white',
height: '90%',
borderRadius: sizes.radius,
}}>
<View style={{flexDirection: 'row'}}>
<View style={{justifyContent: 'center'}}>
<Image
style={{
width: cardWidth,
height: cardHeight,
borderRadius: 12,
marginLeft: spacing.m,
}}
resizeMode="stretch"
source={item.image}
/>
</View>
<View style={{marginTop: spacing.m, marginLeft: spacing.l}}>
<Text style={{marginBottom: 8}}>{item.title}</Text>
<Text>{item.price}</Text>
</View>
</View>
</View>
</View>
);
})}
</View>
);
};
export default CartItem;
this is my desired image
Use alignItems instead of justifyContent.
alignItems controls how children are aligned within the cross axis of their container, so in the case of a row within the vertical axis. justifyContent applies to the main axis, so the horizontal for a row.
you can give justifyContent to the upper view
<View style={{flexDirection: 'row', justifyContent:"center"}}>
<View style={{justifyContent: 'center'}}>
<Text style={{marginBottom: 8}}>Image</Text>
</View>
</View>

Change footer style based on view height in react native

In react native, how would I go about applying a different footer style depending on the height of a particular ScrollView?
Basically, I want to create a sticky footer for a view that isn't the entire height of the phone and, if the ScrollView is larger, I want to add the footer onto the end of the ScrollView.
Hope that makes at least some sense!
Sample below for demonstration.
ThanksSimon
//If the view is larger than the phone height, have the footer at the bottom of the scroll view
<View style={{flex: 1}}>
<Header navigation={this.prop.navigation}
<Scrollview>
<View>
<Text>Content</Text>
</View>
<View>
<Image source={image} style={styles.footerImage} />
</View>
</ScrollView>
</View>
//If the content view is smaller than the phone size, the view needs to be outside the scrollview and use stick styles
<View style={{flex: 1}}>
<Header navigation={this.prop.navigation}
<Scrollview>
<View>
<Text>Content</Text>
</View>
</ScrollView>
<View>
<Image source={image} style={styles.stickyFooter} />
</View>
</View>
const styles = StyleSheet.create({
footerImage: {
width: Dimensions.get('window').width,
maxHeight: 235,
resizeMode: "contain"
},
stickyFooter: {
flex: 1,
position: 'absolute',
left: 0,
top: 0,
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
},
});
Ciao, you could move the footer position using minHeight on Scrollview css. Something like:
<Scrollview style={styles.scrollview}>
<View>
<Text>Content</Text>
</View>
</ScrollView>
Then in your styles:
const styles = StyleSheet.create({
...
scrollview:{
minHeight: 300 // 300 for example
}
});
In this way, if Scrollview does not contains elements, footer appears after 300. Else, if Scrollview contains elements and his height is greater then 300, footer will be moved down according to Scrollview height.
import React from 'react';
import {
Text,
View,
StyleSheet,
ScrollView,
Dimensions,
Image,
} from 'react-native';
export default function App() {
return (
<View>
<ScrollView>
<View style={styles.body}>
<Text>Body</Text>
</View>
<View style={styles.footer}>
<Text>Footer</Text>
</View>
</ScrollView>
</View>
);
}
const { height } = Dimensions.get('window');
const styles = StyleSheet.create({
body: {
minHeight: height, // This is where the magic happens
backgroundColor: 'blue', // This is just for visual indication
},
footer: {
minHeight: 150,
backgroundColor: 'green' // This is just for visual indication
}
});
Should work for different screen heights.

onPress event not working inside the Animated View when it's position is absolute

I'm building a custom header. onPress event of the touchable opacity component is not working when I give components style prop - 'position:"absolute"' . But it works perfectly when I comment on the style property - position.
I couldn't find a solution for this elsewhere. Please help.
<Animated.View
style={{
elevation:
params !== undefined && params.elevation !== undefined
? params.elevation
: null,
position: "absolute",
top: 0,
left: 0,
backgroundColor:
params !== undefined && params.headerBgColor !== undefined
? params.headerBgColor
: "red",
width: "100%",
height:
params !== undefined && params.changingHeight !== undefined
? params.changingHeight
: 50,
justifyContent: "space-between",
alignItems: "center",
flexDirection: "row",
paddingHorizontal: 20
}}
>
<TouchableOpacity style={{}} onPress={() => console.log("hello")}>
<View style={{}}>
<Image
style={styles.menuIcon}
source={require("../../assets/images/Menu-512.png")}
/>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={() => console.log("image")}>
<View style={{}}>
<Image
style={styles.profImage}
source={require("../../assets/images/user.png")}
/>
</View>
</TouchableOpacity>
</Animated.View>;
You should put your absolutely positioned Animated.View as the last child in the screen component. Otherwise, the view that occupies the rest of the screen will become the responder to touches.
const Screen = () => {
return <View style={{ flex: 1}}>
<View style={{flex: 1}}>
//actual screen content
</View>
<Animated.View // header
...props
></Animated.View>
</View>
In the DOM, the component that comes after another component is put "above" it. So, if you do this, your header will be above the actual screen content view and, therefore, become the responder when pressed.
its working on my case checkout below code:
or checkout my snack example : https://snack.expo.io/#immynk/header_demo
either you missing some params which are providing or getting null on condition check kindly confirm it hope this answer will help you
import * as React from 'react';
import {
Text,
View,
StyleSheet,
Animated,
TouchableOpacity,
Image,
} from 'react-native';
import Constants from 'expo-constants';
export default class App extends React.Component {
render() {
return (
<View>
<Text>Hello this is demo of flexdirection of box color</Text>
<Animated.View
style={{
position: 'absolute',
top: 0,
left: 0,
backgroundColor: 'red',
width: '100%',
height: 50,
justifyContent: 'space-between',
alignItems: 'center',
flexDirection: 'row',
paddingHorizontal: 20,
}}>
<TouchableOpacity style={{}} onPress={() => alert("hello","hello")}>
<View style={{}}>
<Image
source={{ uri: 'https://reactjs.org/logo-og.png' }}
style={{ width: 50, height: 65 }}
/>
</View>
</TouchableOpacity>
<TouchableOpacity style={{}} onPress={() => alert("hello","hello")}>
<View style={{}}>
<Image
source={{ uri: 'https://reactjs.org/logo-og.png' }}
style={{ width: 50, height: 65 }}
/>
</View>
</TouchableOpacity>
</Animated.View>
</View>
);
}
}

How can i create tab bar like this? is there any sample?

how can i create tab bar like this in react native?
google tasks tab bar
is there any sample like this?
Using an Image you can achieve it
Sample Snack : https://snack.expo.io/#msbot01/intelligent-croissant
import * as React from 'react';
import { Text, View, StyleSheet,Image } from 'react-native';
import Constants from 'expo-constants';
import Icon from 'react-native-vector-icons/FontAwesome';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<View style={{backgroundColor:'white', height:'10%', bottom:0, position:'absolute', zIndex:1, width:'100%', justifyContent:'space-between',paddingLeft:15,paddingRight:15, flexDirection:'row', alignItems:'center', shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.8,
shadowRadius: 5 }}>
<View>
<Icon name="bars" size={25} color="grey" />
</View>
<View style={{height:'100%',width:100, backgroundColor:'white'}}>
<Image style={{width:100,paddingBottom:'20%', position:'absolute', zIndex:3, bottom:'61%' }} source={require('./bottom round 2.png')} />
</View>
<View>
<Icon name="ellipsis-v" size={25} color="grey" />
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: 'white',
position:'relative',
}
});
I created one like this with an SVG in the middle. Left and right is an empty view with a width and a background color. In the middle the SVG component. The floating button is made with an absolute position. I don't know if there is a better way to do this, but that's my solution.
I have created one using SVG and path and I took help from following Code
https://itnext.io/reactnative-curved-tabbar-dc62e681c24d
also the github code : https://github.com/alex-melnyk/clipped-tabbar
Hope this is helpful. Thanks

My button isn't spreading across my container

I am trying to set my button style that way, it will be spread across my View. Currently its creating white border on the left and on the bottom of my button (see attached screenshot).
My code:
let {width, height} = Dimensions.get('window');
let photoWidth = width/4;
return (
<View style={{width: width, height: 500}}>
<ScrollView style={{width: width, height: height}}>
<View style={{flexDirection: 'row', width: width, flexWrap: 'wrap'}}>
{
this.state.photos.map((p, i) => {
return (
<SelectedPhoto
key={i}
index={i}
style={{
width: photoWidth,
height: photoWidth,
}}
limit={this.state.supportLength}
photo={p}
onSelectPhoto={this.onSelectPhoto}
onDeselectPhoto={this.onDeselectPhoto}
/>
);
})
}
</View>
</ScrollView>
<View style={{ flexDirection:"row", flexWrap: 'wrap', width: width }}>
<Button
onPress={this.onNext}
containerViewStyle={{width: width}}
backgroundColor={Colors.red}
title='NEXT' />
</View>
</View>
);
I consider Button component you used from react-native. Just remove wrapper flex you added as you set width to it.
<Button
onPress={this.onNext}
containerViewStyle={{width: width}}
backgroundColor={Colors.red}
title='NEXT' />