Problem with UI width-height : "%" vs dimension.get('window') - react-native

So im trying to do a responsive UI ,when i put width or height "100%" in my component its not working in my screen correctly ,but when i put Dimensions.get('window').width * 1 works perfect but i dont understand why.I have read some other questions too in the forum but i still dont get it .Thats not static data?
My component name is books at the near the start of CSS code. Its a container of books.
Thanks in advance.
//React imports
import React, { useState,useEffect} from 'react';
import { StyleSheet, Text, View , Image, Pressable, ScrollView, Modal, Alert, Dimensions , Platform} from 'react-native';
import { useNavigation } from '#react-navigation/native';
//Icon imports
import { FontAwesome } from '#expo/vector-icons';
//APIs imports
import axios from 'axios';
import { Buffer } from "buffer";
//My imports
import Header from './Header';
//.Env imports
import {URL} from '#env';
export default function BooksRented() {
return (
//Container
<View style = {styles.container}>
<Header />
{/* ScrollView for Rent Books */}
<ScrollView>
<View style = {{width:'80%',height:'10%',backgroundColor:'black',alignItems:'center',justifyContent:'center',alignSelf:'center',marginTop:'3%',borderRadius:15,flexDirection:'row'}}>
<FontAwesome name="book" size={24} color="white" />
<Text style = {{color:'white',fontSize:22,marginLeft:'5%'}}>Rent Books</Text>
</View>
<View style = {styles.books}>
{book2.map((item)=>{
return (
<View style = {styles.bookContainer} key = {item.id}>
<Text style = {styles.itemTitle}>
{item.title}
</Text>
{/* Here we are making a book image pressable and keep the book object to use it later as modal */}
<Pressable style = {styles.itemImage} onPress={ () => { setBookShow(item); setModalBookVisible(!ModalBookVisible)}}>
<Image
style = {{width:'100%',height:'100%',borderRadius:15 , marginTop:'5%'}}
source = {{uri :'data:image/png;base64,' + Buffer.from(item.image.data,'hex').toString('base64')}}
/>
</Pressable>
</View>
)
})}
</View>
</ScrollView>
</View>
);
}
//Components Style
const styles = StyleSheet.create({
container:{
backgroundColor:'white',
height:'100%',
width:'100%'
},
//Each element - book
books:{
flexDirection:'row',
flexWrap:'wrap',
justifyContent:'center',
alignItems:'center',
backgroundColor:'red',
width: Dimensions.get('window').width * 1, ** <-------Thats my Component **
height: Dimensions.get('window').height * 1 ** <-------Thats my Component **
},
bookContainer:{
alignItems:'center',
justifyContent:'center',
backgroundColor:'black',
borderRadius:15,
margin:'3%',
padding:'3%',
width: Dimensions.get('window').width * 0.35,
height: Dimensions.get('window').height * 0.30
},
itemTitle:{
textAlign:'center',
width:'80%',
fontWeight:'bold',
fontSize : 12,
color:'white'
},
itemImage:{
width:'90%',
height:'80%',
alignItems:'center',
justifyContent:'center',
borderRadius:15,
},
//Modal for Books
bookModal:{
alignItems:'center',
height:Platform.OS ==='ios' ? '70%' : '80%',
width:'80%',
backgroundColor:'black',
marginTop:Platform.OS ==='ios' ? '40%' : '19%',
marginLeft:'10%',
borderRadius:25,
borderWidth:1,
elevation:15
},
//Modal Texts
bookShowTitleText:{
textAlign:'center',
fontWeight:'bold',
color:'white',
fontSize: 15
},
bookShowCategoryText:{
textAlign:'center',
color:'white',
fontSize : 15
},
textInsideModal:{
textAlign:'center',
color:'white',
fontSize : 14
},
bookShowDescribeText:{
textAlign:'center',
fontWeight:'bold',
fontSize : 15
},
scrollViewForDescribeModal:{
backgroundColor:'white',
flexDirection:'column',
padding:'5%'
},
describeText:{
fontSize : 15
},
//Modal pressables
pressableInsideModal:{
borderWidth:6,
borderRadius:11,
elevation:5,
backgroundColor:'grey',
width:'45%',
height:Platform.OS ==='ios' ? '7%' : '9%',
paddingTop:'2%',
alignItems:'center'
},
});

Related

how to make background blur when modal open ups in reactnative

import React from 'react'
import { View, StyleSheet, Text, TouchableOpacity, Modal } from 'react-native'
const ModalContent = ({ visiblity, toggleModal }) => {
return (
<Modal animationType='slide' transparent={true} visible={visiblity} onRequestClose={() => {
toggleModal()
}} >
<View style={styles.container}>
<TouchableOpacity>
<Text style={styles.textButton}>Edit</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.textButton}>Invite</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.textButton}>Delete</Text>
</TouchableOpacity>
</View>
</Modal>
)
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'white',
borderTopRightRadius: 25,
borderTopLeftRadius: 25,
height: 150,
alignItems: 'center',
elevation: 10,
alignItems: 'flex-start',
justifyContent: 'space-around',
paddingLeft: 20,
marginTop: 420
},
textButton: {
fontSize: 13,
color: 'black',
}
})
export default ModalContent
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
import React from 'react'
import { View, StyleSheet, Text, TouchableOpacity, Modal } from 'react-native'
const ModalContent = ({ visiblity, toggleModal }) => {
return (
<Modal animationType='slide' transparent={true} visible={visiblity} onRequestClose={() => {
toggleModal()
}} >
<View style={styles.container}>
<TouchableOpacity>
<Text style={styles.textButton}>Edit</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.textButton}>Invite</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.textButton}>Delete</Text>
</TouchableOpacity>
</View>
</Modal>
)
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'white',
borderTopRightRadius: 25,
borderTopLeftRadius: 25,
height: 150,
alignItems: 'center',
elevation: 10,
alignItems: 'flex-start',
justifyContent: 'space-around',
paddingLeft: 20,
marginTop: 420
},
textButton: {
fontSize: 13,
color: 'black',
}
})
export default ModalContent
just simply adding backgroundcolor with opacity>>>>
backgroundColor: rgba(255, 0, 0, 0.2);
because in modal there is view contains view so if you give background color to that conatining view it will added blacky effect
In case you are using expo use
import { BlurView } from 'expo-blur';
When I added a blurView to my project, I browsed around for some third party libs and ended up with adding react-native-unimodules.
https://www.npmjs.com/package/#react-native-community/blur
you can use blurview so you can trigger blur when the bottomsheet opens or else make it normal
.
.
.
.
const [opensheet,setopensheet]=useState(false)
const [blur,setblur]=useState(0)
const ViewRef=useRef()
useEffect(
()=>
{
const changeBlur=()=>
{
if(opensheet)
setblur(25)
else
setblur(0)
}
changeBlur()
},
[opensheet]
)
.
.
.
return
(
<BlurView
ref={ViewRef}
blurAmount={blur}
>
.
.
.
)
--here opensheet is state of your modal which is defined by bool open/true and close/false
you have multiple way to solve this
one is using this library
https://github.com/Kureev/react-native-blur
one is with image with opacity blurradius
<Image
style={{opacity:0.8}
resizeMode='cover'
source={path}
blurRadius={1}
/>
another approach would to drop shadow with transparent background
i would go with first option becuase i already tried it

React Native Modal: Transparent Background & Layout Problem

I am using the React Native Modal, I want the background of the Modal
to be transparent and I want the Modal display to behalf of the
screen
How to achieve the same requirement, where I am going wrong?
Below is the code for the same, please have a look at this:
import React, { Component } from 'react'
import { Modal, View, Text, Dimensions, Platform, TouchableOpacity, Alert, StyleSheet, Button } from 'react-native'
import Icon from 'react-native-vector-icons/Entypo'
const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;
export class MyComponent extends Component {
render = () => {
const message = 'Do you want to upload the video now or wait until you are connected to wi-fi?'
return (
<Modal
animationType='slide'
transparent={true}
style={{backgroundColor: 'black'}}
>
<View style={styles.content}>
<View style={styles.closeBtn}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('PreInspection_VideoPlayer')} style={styles.closeBtn}>
<Icon name="cross" color="#000" size={26} />
</TouchableOpacity>
</View>
<Text style={{
fontSize: 18,
fontFamily: 'Montserrat-Bold',
paddingTop: Platform.OS === 'android' ? 40 : 20,
paddingVertical: 10
}}>Warning! 🚨</Text>
<View style={{ paddingHorizontal: 40 }}>
<Text style={{ fontSize: 18, justifyContent: 'center', alignItems: 'center', textAlign: 'center' }}>{message}</Text>
</View>
<Button
title='Upload My Video'
style={styles.bigButtons}
onPress={() => { Alert.alert('Uploading Video') }}
/>
<Button
title='Upload Video Later'
style={styles.bigButtons}
onPress={() => { Alert.alert('Uploading Video Later') }}
/>
</View>
</Modal>
)
}
}
const styles = StyleSheet.create({
closeBtn: {
padding: 10
},
bigButtons: {
width: 240,
marginTop: 20
},
content: {
backgroundColor: 'red',
width: windowWidth * 0.8,
height: windowHeight * 0.7,
alignSelf: 'center',
top: windowHeight * 0.15,
borderRadius: windowHeight * 0.03,
alignItems: 'center',
justifyContent: 'center'
},
})
Any help would be appreciated. Thanks in advance :)
You can achieve this easily with React Native Community Modal
Here is an example:
import React, { useState } from "react";
import { Text, View, Dimensions } from "react-native";
import Modal from "react-native-modal";
const { width: ScreenWidth, height: ScreenHeight } = Dimensions.get("window");
const ModalExample = props => {
const [visibility, setVisibility] = useState(true);
return (
<View>
<Modal
backdropColor="transparent"
isVisible={visibility}
style={{
alignItems: "center",
justifyContent: "center"
}}
onBackdropPress={() => setVisibility(false)}
>
<View
style={{
borderRadius: 16,
alignItems: "center",
justifyContent: "center",
width: ScreenWidth * 0.7,
backgroundColor: "#fdfdfd",
height: ScreenHeight * 0.5
}}
>
<Text>I am the modal content!</Text>
</View>
</Modal>
</View>
);
};
export default ModalExample;

Accessing variables defined in component state in StyleSheet.create? (undefined is not an object (evaluating 'this.state.filterMenuHeight'))

I want to animate the entry of a component.
So I defined an animated variable in my component state.
But when trying to refer to it from StyleSheet.create I get the undefined is not an object error.
This is my component code:
I tried replacing this.state.filterMenuHeight with .state.filterMenuHeight, but still getting the same error.
I can access variables if they are defined in an external file though.
import React, { Component } from 'react'
import {
Animated,
StyleSheet,
Button,
StatusBar,
View,
TextInput,
Text,
Keyboard,
Platform,
FlatList
} from 'react-native'
import { Icon } from 'react-native-elements'
import Modal from 'react-native-modalbox'
import Modal2 from'react-native-swipe-up-down'
import { SafeAreaView } from 'react-navigation'
import ScreenName from './ScreenName'
import ScreenNames from '../constants/ScreenNames'
import Colors from '../constants/Colors';
import FilterMenu from './FilterMenu';
export default class RequestBulletin extends Component {
constructor(props) {
super(props)
this.handleScroll = this.handleScroll.bind(this)
this.state = {
titleFilterText: "",
scrollOffsetY: 0,
filterMenuHeight: new Animated.Value(0)
}
this.data = [
<View key="1" style={styles.item}/>,
<View key="2" style={styles.item}/>,
<View key="3" style={styles.item}/>,
<View key="4" style={styles.item}/>,
<View key="5" style={styles.item}/>,
<View key="6" style={styles.item}/>,
<View key="7" style={styles.item}/>,
<View key="8" style={styles.item}/>,
<View key="9" style={styles.item}/>,
<View key="10" style={styles.item}/>,
<View key="11" style={styles.item}/>,
<View key="12" style={styles.item}/>
]
}
handleScroll = function(event) {
this.setState({scrollOffsetY:event.nativeEvent.contentOffset.y})
}
render() {
return (
<SafeAreaView style ={styles.container}>
<View style={{flexDirection:'row', marginLeft:20,marginRight:20}}>
<TextInput
style={{flex:1, height: 40, marginRight:10, borderWidth:1, borderColor: Colors.GrayAccent, borderRadius:5}}
onChangeText={(titleFilterText) => this.setState({titleFilterText})}
/>
<Icon
type='font-awesome'
name="sliders"
size={25}
color={Colors.GrayAccent}
onPress={()=> {this.refs.modal1.open()}}
/>
</View>
<Text>
{this.state.scrollOffsetY}
</Text>
<ScreenName ScreenName="Bullentin"/>
<Button
title = "Dashboard"
onPress = {() => {
props.navigation.navigate(ScreenNames.Dashboard, {
calledFrom : ScreenNames.Bulletin
})
}}
style = {{width: '200'}}
/>
<Animated.View
style={styles.filterMenu}
>
<FlatList
style= {{flex:1, width: '100%'}}
data= {this.data}
renderItem = {({item}) => item}
onScroll={this.handleScroll}
/>
</Animated.View>
</SafeAreaView>
);
}
}
let styles = StyleSheet.create({
container: {
paddingTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight,
flex: 1,
justifyContent: 'flex-start',
alignItems: 'center',
width:'100%'
},
filterMenu: {
position: 'absolute',
backgroundColor: 'pink',
opacity: .6,
width: '100%',
bottom: 40,
height: this.state.filterMenuHeight
},
item: {
height: 80,
width:'100%',
margin: 10,
marginRight: 10,
backgroundColor: 'red'
}
})
Right now I am making it work using this:
<Animated.View style={[styles.filterMenu, { height: this.state.filterMenuHeight }]}
>
<FlatList
style= {{flex:1, width: '100%'}}
data= {this.data}
renderItem = {({item}) => item}
onScroll={this.handleScroll}
/>
</Animated.View>
I know this question is similar to another question
Accessing state value from StyleSheet.create in ReactNative
But the issue with the answer there is that it's very similar to my fix. Essentially 2 different style sheets are squished into one.
This will quickly become inefficient it the number of objects to style is more than 1.
So can what I want to do be done without StyleSheet.flatten()?

navigate.dispatch(DrawerActions.closeDrawer()) not working in React Native

On click of a cross button the drawer should be closed, that is the
thing I am trying. I have passed down the props inside component but
giving error that navigate.dispatch(DrawerActions.closeDrawer()) is
undefined.
I am providing My code
SideMenu.js which the layout of drawer menu. From here I am passing
props to drawerheader.
import React, {Component} from 'react';
import { View, StyleSheet} from 'react-native';
import DrawerHeader from './DrawerHeader';
import DrawerMenu from './DrawerMenu';
import { StackNavigator } from 'react-navigation';
class SideMenuLayout extends Component {
state = {
menuNames:[{
id:'0',
name:'My Profile',
link:''
},{
id:'1',
name:'Place Order',
link:''
},{
id:'2',
name:'Order History',
link:'OrderHistory'
},{
id:'3',
name:'Payment',
link:''
},{
id:'4',
name:'Recharge',
link:''
},{
id:'5',
name:'Help',
link:''
},{
id:'6',
name:'Logout',
link:''
}]
}
render () {
return (
<View style={styles.container} >
<DrawerHeader navigation={this.props.navigation}/>
<DrawerMenu
navigation={this.props.navigation}
menuItems={this.state}
style={{ marginTop: 106/3}}
/>
</View>
);
}
}
export default SideMenuLayout;
const styles = StyleSheet.create({
container:{
flex:1,
backgroundColor: "#ffffff",
}
});
Drawer Header code goes here. Here I am trying to close the navigation drawer.
import React, {Component} from 'react';
import {Text, View, StyleSheet,Image,TouchableOpacity} from 'react-native';
import { FontAwesome } from '#expo/vector-icons';
import { DrawerActions, StackNavigator } from 'react-navigation';
const DrawerHeader = (props)=> {
const { navigate } = props.navigation;
return (
<View style={{backgroundColor: '#d61822',width:DRAWER_CONTAINER_WIDTH/3,height:DRAWER_CONTAINER_HEIGHT/3 }}>
<View style={styles.titleContainer}>
<View style={{ marginLeft:20, backgroundColor:'#d61822',height:40 }}>
<Text style={{fontSize:28,fontStyle:'italic',color:'#ffff',fontWeight:'bold'}}>
Prabhuji Online
</Text>
</View>
<View style={{ marginLeft:35,backgroundColor:'#d61822',width: 50, height: 40,paddingRight:10,alignItems:'center',justifyContent:'center' }}>
<TouchableOpacity onPress={()=>navigate.dispatch(DrawerActions.closeDrawer())}>
<Text style={{fontSize:20,color:'#ffff',}}>
<FontAwesome
style={{ alignSelf: 'flex-end'}}
name="times"
size={18}
color="#ffffff"
/>
</Text>
</TouchableOpacity>
</View>
</View>
<View style={styles.fakeContainer}>
</View>
<View style={{
position:'absolute',
top: 170/3,
marginLeft:20,
width:220/3,
height:220/3,
backgroundColor:'#fffcf9',
borderRadius:(220/3)/2,
justifyContent:'center',
alignContent:'center',
alignItems:'center',
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 5,
},
shadowOpacity: 0.25,
shadowRadius: 6.27,
elevation: 7,
}}>
<Image
tintColor='red'
style={{
width: 111/3,
height: 111/3,
}}
source={require('../../../assets/place_order.png')}/>
</View>
</View>
);
}
export default DrawerHeader;
const styles = StyleSheet.create({
titleContainer:{
backgroundColor: '#d61822',
flexDirection: 'row',
height:TITLE_CONTAINER_HEIGHT/3,
marginTop: 50/3,
},
fakeContainer:{
position:'relative',
height:FAKE_CONTAINER_HEIGHT/3,
backgroundColor: '#ffffff',
//backgroundColor: 'yellow',
}
});
Can any one please tell me what is going wrong here?
I have also tried navigate.closeDrawer(). But same error is giving.
Instead of using the navigate call, you need to dispatch the action like this: this.props.navigation.dispatch(*your action here*), as described in the docs: https://reactnavigation.org/docs/en/navigation-prop.html#dispatch-send-an-action-to-the-router

React native align icon and text

for the love of God, every styling i put on the stylesheet doesn't change anything.
i tried style the view, sectionheader & sectionbox but no luck
i want to align 4 icons in the boxsection and text below then as such, please any help would be appreciated.
export default class HomePage extends Component {
render() {
return (
<View>
<SectionHeader title={'Food'} />
<View >
<SectionBox >
<Icon style={styles.icons} name="icon name" size={50} />
<Icon style={styles.icons} name="icon name" size={50} />
<Icon style={styles.icons} name="icon name" size={50} />
<Icon style={styles.icons} name="icon name" size={50} />
<Text style={styles.sectiontext}>burgers</Text>
</SectionBox>
</View>
const styles = StyleSheet.create({
icons: {
flexDirection: 'row',
paddingTop: 7,
paddingLeft: 5,
},
sectiontext: {
fontSize: 15,
fontWeight: 'bold',
paddingLeft: 5,
alignItems: 'center',
}
});
For the icons-containing-box you would need to indicate flexDirection and flexWrap, not directly on the icon's style. Then to get the text below each icon you need to wrap icon and text in its own view and give that 'column' direction.
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { Ionicons } from '#expo/vector-icons';
import { Constants } from 'expo';
const ICON_SIZE = 70;
const FONT_SIZE = 18;
const getItem = () => (
<View style={styles.iconStyle}>
<Ionicons name="md-checkmark-circle" size={ICON_SIZE} color="green" />
<Text style={styles.textStyle}>name</Text>
</View>
);
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<View style={styles.iconContainer}>
{getItem()}
{getItem()}
{getItem()}
{getItem()}
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
iconContainer: {
width: ICON_SIZE * 2,
flexDirection: 'row',
flexWrap: 'wrap',
},
iconStyle: {
flexDirection: 'column',
alignItems: 'center',
padding: 5,
},
textStyle: {
fontSize: FONT_SIZE,
},
});
You need a view for each group of icon and text with a flexDirection: 'column' and one another view for each row (or column), like the example below:
https://snack.expo.io/HJY7IWsFm
Other option is to use a GridView lib:
https://github.com/saleel/react-native-super-grid