Can't render Card from react-native-elements - reactjs

I have been simply trying to render a card from react-native-elements UI library. Here is the documentation that I've been looking through and literally copied and pasted from: https://reactnativeelements.com/docs/1.2.0/card
Here is my Deal component:
import { View } from 'react-native'
import { Card, ListItem } from 'react-native-elements'
const Deal = () => {
const users = [
{
name: 'brynn',
avatar: 'https://www.w3schools.com/howto/img_avatar2.png',
},
]
return (
<View>
<Card containerStyle={{ padding: 0 }}>
{users.map((u, i) => {
return (
<ListItem
key={i}
roundAvatar
title={u.name}
leftAvatar={{ source: { uri: u.avatar } }}
/>
)
})}
</Card>
</View>
)
}
export default Deal
Here is my SecondScreen component in which I am trying to render Deal:
import { StyleSheet, Text, View } from 'react-native'
import Step from '../components/Step'
import MyCarousel from '../components/MyCarousel'
import Ratings from '../components/Ratings'
import Deal from '../components/Deal'
export default function SecondScreen({ route, navigation }) {
const { image } = route.params
return (
<>
<View>
<Text
style={{ fontSize: '16px', marginLeft: 10, marginTop: 15 }}
>
Daily Deals
</Text>
<View
style={{
borderBottomColor: 'black',
borderBottomWidth: StyleSheet.hairlineWidth,
}}
/>
<View style={{ marginTop: 10 }}>
<Deal />
</View>
</View>
</>
)
}
Here is what it renders at the end:
Any help would be appreciated!
Edit: I have decided to use another component in the meantime. This seems like possibly deprecated component or something.

Try adding flex or height for <View />
<View style={{ flex: 1, marginTop: 10 }}>
<Deal />
</View>

Inside your Deal component, you have a <View /> wrapper around the <Card /> component. The one inside Deal file, NOT the one wrapping it in SecondScreen file.
Have you tried removing that excess <View />?
If you want to keep that <View />, have you tried giving that specific <View /> a style={{ height: 100px }} or style={{ flex: 1 }} property?

Related

I want to pass data to another screen by FlatList in react native

Hello guys am new on react native I want to build an app like news app with posts,I stack in how to pass the data in flatlist to another screen to open the screen with the post data i use V6 navigation Note I do the Navigation and the post touchable this is my code :
the import :
import { StyleSheet, Text, View ,Button ,FlatList,TouchableOpacity } from 'react-native';
import React,{useState} from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
Screen one :
function HomeScreen({navigation}) {
const [news,setnews]=useState([
{title:'React Native students can get the basic knowledge',by:'Chris brown',dateTime:'15 may',key:'1'},
{title:'whats happening here is that you are trying to',by:'charley',dateTime:'15 jan',key:'2'},
{title:'statuses. specifically, you have to look here:',by:'yami',dateTime:'15 jon',key:'3'},
{title:'screen you want to show, when the authentication status changes.',by:'maria',dateTime:'15 nov',key:'4'},
]);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<FlatList
data={news}
renderItem={({item})=>(
<TouchableOpacity onPress={()=>navigation.navigate('Detials' ,item)}>
<Text style={{fontSize:15,}}>{item.title}</Text>
</TouchableOpacity>
)}
/>
</View>
);
}
screen two:
function DetialsScreen({navigation}) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>{navigation.getParam('title')}</Text>
</View>
);
}
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Detials" component={DetialsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
screenone :
<FlatList
data={news}
renderItem={({item})=>(
<TouchableOpacity onPress={()=> this.props.navigation.navigate('ScreenTwo' , item)}>
<Text style={{fontSize:15,}}>{item.title}</Text>
</TouchableOpacity>
)}
/>
at screentwo you can get using this.props.route.params
export default class ScreenTwo extends Component {
constructor(props, ctx) {
super(props, ctx);
this.state = {
news: this.props.route.params
};
}
render() {
const news = this.state.news
return (
<View style={{flex: 1, margin: 30}}>
<Text>Title is : {news.title}{'\n'}{'\n'}by {news.by}</Text>
<Button
style={{marginTop: 20}}
onPress={() => this.props.navigation.goBack()}
title="Back"
color="#841584"
/>
</View>
);
}
}
for snack you can try here : https://snack.expo.dev/#edoofx/example1111
im using class anyway :D

React Native Add Top thin header

hello I'm developing a react native app everything is fine but I have a problem
return (
<SafeAreaView style={styles.safeArea}>
<View style={styles.container}>
<StatusBar
translucent={true}
backgroundColor={'rgba(0, 0, 0, 0.3)'}
barStyle={'light-content'}
/>
{ this.gradient }
<ScrollView
style={styles.scrollview}
scrollEventThrottle={200}
directionalLockEnabled={true}
>
{ carousel }
<FlatList
data={ this.state.GridListItems }
renderItem={ ({item}) =>
<TouchableOpacity
style={styles.GridViewContainer}
onPress={() => this.props.navigation.push('ProfileScreen', { height: "6'2", category: item.key })}>
<ImageBackground
source={{ uri: item.img }}
style={{width: '108%', height: '110%', justifyContent:'center'}}
>
<Text style={styles.GridViewTextLayout} > {item.key} </Text>
</ImageBackground>
</TouchableOpacity>
}
numColumns={2}
/>
</ScrollView>
</View>
</SafeAreaView>
);
styles
safeArea: {
flex: 1,
backgroundColor: colors.black
},
container: {
flex: 1,
backgroundColor: colors.background1
},
when I scroll down you see the mobile battery and wifi (top bar) is in the app
I want the app to be below the mobile topbar how can I achieve that?
here is an expo qr code
once try this and let me know your results:
import React,{Fragment} from 'react';
return (
<Fragment>
<SafeAreaView style={{ flex: 0, backgroundColor: 'red' }} />
<SafeAreaView style={styles.safeArea}>
<View style={styles.container}>
{ this.gradient }
<ScrollView
style={styles.scrollview}
scrollEventThrottle={200}
directionalLockEnabled={true}
>
{ carousel }
<FlatList
data={ this.state.GridListItems }
renderItem={ ({item}) =>
<TouchableOpacity
style={styles.GridViewContainer}
onPress={() => this.props.navigation.push('ProfileScreen', { height: "6'2", category: item.key })}>
<ImageBackground
source={{ uri: item.img }}
style={{width: '108%', height: '110%', justifyContent:'center'}}
>
<Text style={styles.GridViewTextLayout} > {item.key} </Text>
</ImageBackground>
</TouchableOpacity>
}
numColumns={2}
/>
</ScrollView>
</View>
</SafeAreaView>
);
i added safeareaview (flex:0) for statusBar you can apply any color you want.
provide options in your navigator file as:
navigationName: {
screen: fileName,
navigationOptions: ({ navigation }) => {
if (Platform.OS === "android") {
return {
title: 'images',
headerStyle: {
backgroundColor: '#382464',
height: 50,
},
headerTitleStyle: {
color: '#fff',
},
headerTintColor: '#fff',
// header: props => <UriBar {...props} />
}
} else {
return {
header: null
}
}
}
},
you can also use statusBar for android
You should use SafeAreaView.
It will render your component without overlapping the "top bar".
import { SafeAreaView } from 'react-native'
...
return (
<SafeAreaView>
// your components
<SafeAreaView/>
)
Edit:
As you can see in the docs.
Simply wrap your top level view with a SafeAreaView with a flex: 1 style applied to it. You may also want to use a background color that matches your application's design.
So if you already using SafeAreaView, maybe you don't have flex: 1 and it's not working in the way you want.

How to reduce the huge space between components in the screen?

I'm new to react native development and I have a problem hope someone can help me!
I'm trying to show some components in a screen, I'm using native base and when I try to put the HomeHeader component and the MainSection component together in the Home Screen, They show with a huge space between them and if I try to duplicate the components, white space is shown between them also!
I don't know why this happens and I hope if someone can help me
Attached code and screenshots for the result on the genymotion emulator
Thanks in advance!
Home.js
import React from "react";
import { Container, Header, Content } from "native-base";
import { ImageBackground, Image, ScrollView } from "react-native";
import MainSection from "../Components/MainSection";
import HomeHeader from "../Components/HomeHeader";
export default class Home extends React.Component {
static navigationOptions = {
header: null
};
render() {
return (
<Container>
<Content>
<HomeHeader />
<MainSection />
<MainSection />
<MainSection />
</Content>
</Container>
);
}
}
HomeHeader.js
import React from "react";
import { Container, Text } from "native-base";
import { Image, ImageBackground } from "react-native";
export default class HomeHeader extends React.Component {
render() {
return (
<Container>
<ImageBackground
source={require("../Assets/Backgrounds/home-header.png")}
style={{
width: null,
flex: 1,
height: 130,
flexDirection: "row",
justifyContent: "center"
}}
>
</ImageBackground>
</Container>
);
}
}
MainSection.js
import React from "react";
import { Container, Content, Text, Button, View } from "native-base";
import { ImageBackground, Image, ScrollView } from "react-native";
export default class MainSection extends React.Component {
render() {
return (
<Container>
<Content>
<View
style={{
flex: 1,
flexDirection: "row",
marginTop: 13
}}
>
<Image
source={require("../Assets/Vector_Icons/home-first-icon.png")}
style={{ height: 50, width: 50, marginLeft: 25 }}
/>
<Text style={{ marginTop: 15, marginLeft: 10, marginRight: 50 }}>
Places For Going Out
</Text>
<Button transparent success style={{ marginTop: 3 }}>
<Text>View More</Text>
</Button>
</View>
<View
style={{
flex: 1,
flexDirection: "row",
marginTop: 13,
marginLeft: 25
}}
>
<ScrollView
horizontal={true}
showsHorizontalScrollIndicator={false}
>
<Image
source={require("../Assets/Backgrounds/splash-bg.png")}
style={{
width: 150,
height: 150,
borderRadius: 5,
marginRight: 10
}}
/>
<Image
source={require("../Assets/Backgrounds/splash-bg.png")}
style={{
width: 150,
height: 150,
borderRadius: 5,
marginRight: 10
}}
/>
<Image
source={require("../Assets/Backgrounds/splash-bg.png")}
style={{ width: 150, height: 150, borderRadius: 5 }}
/>
</ScrollView>
</View>
</Content>
</Container>
);
}
}
Result

React Native Modal not showing up

I am trying to show a modal without going to another screen, I want it to be displayed on the current screen but not through navigation. The modal doesn't pop up and I don't know the problem.
I am using the renderModal to show the modal on the screen.When I use this.props.navigation.navigate('AnotherModal'), it works but goes to another screen,this time I want to show modal on the same screen.
import * as React from 'react';
import { Text, View, Image,
StyleSheet,Alert,Modal,TouchableHighlight } from 'react-native';
import { Constants } from 'expo';
import { Appbar, Colors, FAB } from 'react-native-paper';
import ProductsModal from './ProductsModal';
import ModalTester from './ModalTester';
export default class AppBar extends React.Component {
state = {
modalVisible: false,
};
setModalVisible(visible)
{
this.setState({modalVisible: visible});
}
renderModal() {
return (
<Modal
animationType="slide"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}>
<View style={{marginTop: 22}}>
<View>
<Text>Hello World!</Text>
<TouchableHighlight
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<Text>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
);
}
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.appbar}>
<Appbar style={styles.piece}>
<Appbar.Action
icon={require('../../assets/devices.png')}
onPress={this.renderModal.bind(this)}
/>
</Appbar>
<View>
<Image
source={require('../../assets/cutout.png')}
style={styles.cutout}
pointerEvents="none"
/>
<FAB
icon={require('../../assets/add_circle.png')}
color="#b2beb5"
onPress={() => navigate('Homes')}
style={styles.fab} />
</View>
<Appbar style={[styles.piece, styles.right]}>
<Appbar.Action
icon={require('../../assets/account_box.png')}
onPress={() => console.log('Account pressed')}
/>
</Appbar>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
//backgroundColor: '#ecf0f1',
padding: 8,
},
appbar: {
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
height: 56,
flexDirection: 'row',
},
piece: {
flex: 1,
backgroundColor: Colors.grey300,
},
right: {
justifyContent: 'flex-end',
},
cutout: {
height: 56,
width: 80,
tintColor: Colors.grey300,
},
fab: {
position: 'absolute',
margin: 12,
bottom: 16
}
});
You should try to bind your setModalVisible in the constructor first:
constructor(props) {
super(props);
this. setModalVisible = this. setModalVisible.bind(this);
}
And then change your first Appbar.Action to something like this:
<Appbar.Action
icon={require('../../assets/devices.png')}
onPress={() => this. setModalVisible(true)}
/>
Also you have to add your Modal to the rendered code
...
<Appbar.Action
icon={require('../../assets/account_box.png')}
onPress={() => console.log('Account pressed')}
/>
</Appbar>
{this.renderModal()}
</View>
I'm not sure the bind is necessary though
Since screen does not change, your Modal needs to be within the render method of that screen. This means it can be handled by the state of the component. For example to show it you can:
<Appbar.Action
icon={require('../../assets/devices.png')}
onPress={() => this.setModalVisible(true)}
/>
In the main render you can just add directly your renderModal, 'cause its visible prop is sufficient to handle the behavior:
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.appbar}>
<Appbar style={styles.piece}>
<Appbar.Action
icon={require('../../assets/devices.png')}
onPress={this.renderModal.bind(this)}
/>
</Appbar>
<View>
{this.renderModal()}
<Image
source={require('../../assets/cutout.png')}
style={styles.cutout}
pointerEvents="none"
/>
<FAB
icon={require('../../assets/add_circle.png')}
color="#b2beb5"
onPress={() => navigate('Homes')}
style={styles.fab} />
</View>
<Appbar style={[styles.piece, styles.right]}>
<Appbar.Action
icon={require('../../assets/account_box.png')}
onPress={() => console.log('Account pressed')}
/>
</Appbar>
</View>
);
}

Tap outside of modal to close modal (react-native-modal)

Anyone has experience of implementing react-native-modal?
While I'm using it, modal isn't closed when I tap outside of modal.
Here is what I've tried
Adding onBackdropPress(() => {this.props.hideModal()})
Adding TouchableWithoutFeedback inside and outside of components
and many other approaches...
Here is my the screen where I want to show my modal.
render() {
return (
<View style={{flex: 1}}>
<ScrollView>
// CONTENT HERE
{this._renderModal()} //rendering modal here
<FABs onFABsPress={this._showModal} /> // I open Modal when I press the FABs button
</ScrollView>
</View>
)
);
_renderModal = () => {
return (
<CameraImageSelectModal
hideModal={this._hideModal}
isModalVisible={this.state.isModalVisible}
navigation={this.props.navigation}
/>
)
}
Here is modal component : CameraImageSelectModal.js
render() {
let { isModalVisible } = this.props;
return (
<View>
<Modal
isVisible={isModalVisible}
onBackdropPress={() => {console.log('hey')}}>
transparent={true}>
<View style={styles.modalContainer}>
<View style={styles.modalTitleTextContainer}>
<Text style={styles.modalTitleText}>Hello World</Text>
</View>
<View style={styles.modalContentTextContainer}>
<Text style={styles.modalContentText}></Text>
</View>
<View style={styles.modalButtonContainer}>
<Button transparent onPress={this._handleCameraPress}>
<Text style={[styles.modalText, styles.black]}>Camera</Text>
</Button>
<Button transparent onPress={this._handleAlbumPress}>
<Text style={styles.modalText}>Album</Text>
</Button>
</View>
</View>
</Modal>
</View>
Thanks!!
I don't think the modal has that built in functionality, but you could create your own component that does. Here is a quick implementation. You might have to mess around with padding and margin to get it how you like, but this will allow the modal to be dismissed when pressing outside.
import React, { Component } from "react"
import { Modal, StyleSheet, View, TouchableHighlight } from "react-native"
const styles = StyleSheet.create({
container: {
zIndex: 1,
margin: 25,
backgroundColor: "white"
},
background: {
flex: 1
},
outerContainer: {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: "center"
}
})
const MyModal = props => (
<Modal transparent={true} animationType={"slide"} visible={props.visible} onRequestClose={() => props.onRequestClose()}>
<TouchableHighlight style={styles.background} onPress={() => props.onRequestClose()} underlayColor={"transparent"}>
<View />
</TouchableHighlight>
<View style={ styles.outerContainer }>
<View style={styles.container}>
{props.children}
</View>
</View>
</Modal>
)
export { MyModal }
I just figured out why onBackdropPress = {() => console.log("Pressed")} didn't work..!!! onBackdropPress property was added since its version 3.xx and I was using 2.5.0 version.
So yarn update react-native-modal solved the issue.
If anyone encounters the problem that the library/component doesn't work as expected as you seen on documentation, try to check your package version number!
Cheers!
<Modal
isVisible={isModalVisible}
customBackdrop={
<View
style={styles.backDropContainer}
onTouchEnd={() => setModalVisible(false)}
/>
}
onBackdropPress={() => setModalVisible(false)}>
<View style={styles.modalContainer}>
<FlatList data={DATA} renderItem={() => <Text>hehehe</Text>} />
</View>
</Modal>
Style:
const styles = StyleSheet.create({
backDropContainer: {
flex: 1,
backgroundColor: 'black',
opacity: 0.5,
},
modalContainer: {
flex: 0.5,
backgroundColor: 'white',
padding: 10,
borderRadius: 10,
},
});

Resources