How to make my Bottom Bar fixed in React Native? - javascript

Hey
I have my bottom bar out the Scroll View component,But it still scroll with the other components.
How can i make it fixed ?
"
<SafeAreaView styles={SafeViewAndroid.AndroidSafeArea}>
<View style={{ backgroundColor: "#fff", padding: 15 }}>
<HeaderTabs activeTab={activeTab} setActiveTab={setActiveTab} />
<SearchBar cityHandler={setCity} />
</View>
<ScrollView showsVerticalScrollIndicator={false}>
<Categories />
<RestaurantItems restaurantData={restaurantData} />
</ScrollView>
<Divider width={1} />
<BottomTabs />
</SafeAreaView>
"
Entire Code Screen

You can use flex proportions to separate the and components, as below
<SafeAreaView styles={SafeViewAndroid.AndroidSafeArea}>
<View style={{ backgroundColor: "#fff", padding: 15, flex : 1 }}>
<HeaderTabs activeTab={activeTab} setActiveTab={setActiveTab} />
<SearchBar cityHandler={setCity} />
</View>
<View style= {{flex : 3 }}>
<ScrollView showsVerticalScrollIndicator={false}>
<Categories />
<RestaurantItems restaurantData={restaurantData} />
</ScrollView>
</View>
<View style= {{flex : 1 }}>
<Divider width={1} />
<BottomTabs />
</View>
</SafeAreaView>

You can do it by styling your button component as -
<TouchableOpacity
style={{
width: 60,
height: 60,
backgroundColor: 'red',
position: 'absolute',
bottom: 50,
justifyContent: 'center',
alignItems: 'center',
}}
onPress={() => {
console.log('Button Pressed')
}}
>
<Text>Hello Bottom Button</Text>
</TouchableOpacity>

Related

How to space items in React or React Native

I am trying to space my components however I am having issues. I would like my grid to take up 90% of the screen and the gear icon to take 10%
<View
style={{
paddingLeft: insets.left,
paddingRight: insets.right,
flex: 1,
flexDirection: 'row',
}}
onLayout={event => {
_handleWorkSpace(event);
}}>
<StatusBar hidden={true} />
<View style={{flex: 1}}>
<FlatGrid
itemDimension={96}
// maxDimension={128}
data={items}
style={styles.gridView}
// staticDimension={{width: 128, height: 128}}
fixed
spacing={10}
renderItem={({item}) => (
<View
onLayout={event => {
var {x, y, width, height} = event.nativeEvent.layout;
console.log(width, height);
}}
style={[styles.itemContainer, {backgroundColor: item.code}]}>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemCode}>{item.code}</Text>
</View>
)}
/>
</View>
<View style={{flex: 1}}>
<Icon name="settings" size={30} />
</View>
</View>
What I have
What I am hoping for
I was able to get the look but I had to change the grid flex value to 12. I know it's not the correct way so I am trying to figure how to do this
You put flex: 1 in both Views, this means that both will try to take up 50% of the space (1+1). If you want one to take 90% and the other one 10%, one will need flex: 9 and the other one flex: 1.
Just change the flex values:
<View style={{flex: 9}}>
<FlatGrid
...
/>
</View>
<View style={{flex: 1}}>
<Icon name="settings" size={30} />
</View>
To try to make it clearer: just imagine the sum of the flex values on the same level are 100%. Since you had 2 flex: 1, 1+1=2=100%, so 1=50%.
By making the change I suggested (flex: 9 and flex: 1) you can think of it like 9+1=10=100%, so 9=90% and 1=10%.
const {width} = Dimensions.get('window');
<View
style={{
paddingLeft: insets.left,
paddingRight: insets.right,
flex: 1,
flexDirection: 'row',
}}
onLayout={event => {
_handleWorkSpace(event);
}}>
<StatusBar hidden={true} />
<View style={{width : 0.9*width}}>
<FlatGrid
itemDimension={96}
// maxDimension={128}
data={items}
style={styles.gridView}
// staticDimension={{width: 128, height: 128}}
fixed
spacing={10}
renderItem={({item}) => (
<View
onLayout={event => {
var {x, y, width, height} = event.nativeEvent.layout;
console.log(width, height);
}}
style={[styles.itemContainer, {backgroundColor: item.code}]}>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemCode}>{item.code}</Text>
</View>
)}
/>
</View>
<View style={{width : 0.1*width}}>
<Icon name="settings" size={30} />
</View>
</View>
try this, don't forget to import Dimensions from react-native
use cosnt {width} = Dimensions.... out of return statement.
You can set your gear icon as an absolute element:
<View style={styles.grid}>
<Octicons name="gear" size={iconSize} color="black" style={styles.icon} />
<FlatGrid
itemDimension={130}
data={items}
style={styles.gridView}
spacing={10}
renderItem={({ item }) => (
<View style={[styles.itemContainer, { backgroundColor: item.code }]}>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemCode}>{item.code}</Text>
</View>
)}
/>
</View>
with the following styles:
grid: {
alignSelf: 'center',
width: width * 0.9,
},
icon: {
position: 'absolute',
right: -iconSize,
top: 0,
}
Here is a working snack: https://snack.expo.dev/#hristoeftimov/absolute-icon

Segmented Control In Header

im trying to add a segmented tab to my header let me show you an example before i start.
if you've been on the twitter app you know you can swipe through these tabs while these tabs remain on the header, i cant quite find out how i would complete this tho
Some of the code:
<Stack.Screen name="Find" component={Home} options={{
header: () => (
<View style={{ backgroundColor: 'black', paddingBottom: 10 }}>
<View style={{ paddingLeft: 10, flexDirection: 'row', paddingTop: 25, backgroundColor: 'black' }}>
<View style={{}}>
<View style={{ paddingRight: 10, flexDirection: 'row', alignItems: 'center' }}>
<View>
<Image style={{ width: 30, height: 30, borderRadius: 30 }} source={require('../assets/forever.png'} />
</View>
<View style={{ width: '84%', paddingHorizontal: 10 }}>
<Formik
initialValues={{ formData: "" }}
onSubmit={async (values, { setSubmitting }) => {
setSubmitting(true)
await setData({
values
})
console.log(sdata)
setSubmitting(false)
}}
>
{({ handleChange, handleBlur, handleSubmit, values }) => (
<>
<View
style={{
backgroundColor: '#0D0D0D',
padding: 10,
borderRadius: 18,
flexDirection: 'row',
height: 34
}}
>
<View style={{ alignItems: 'center' }}>
<Icon name="search" type="ionicon" size={15} color="grey" />
</View>
<TextInput
autoCorrect={false}
clearButtonMode="always"
placeholderTextColor="grey"
onChangeText={handleChange('formData.form')}
value={values.formData.form}
onBlur={handleBlur('formData')}
placeholder="Search"
style={{ backgroundColor: '#0D0D0D', paddingHorizontal: 20 }}
/>
</View>
</>
)}
</Formik>
</View>
<View style={{ flexDirection: 'row' }}>
<Icon onPress={() => create.current.show()} type="ionicon" size={28} color="white" name="create-outline" />
</View>
</View>
</View>
</View>
<ScrollableTabView style={{}} renderTabBar={() =>
<DefaultTabBar
style={{
borderWidth: 0,
}}
/>
} tabBarUnderlineStyle={{ backgroundColor: "#fff", borderWidth: 1}} tabBarTextStyle={{ color: "#fff" }} tabBarBackgroundColor="#000">
<View tabLabel="Home">
</View>
<Quotes tabLabel="Quotes" />
<View tabLabel="Posts" >
</View>
<View tabLabel="Home" >
</View>
</ScrollableTabView>
</View>
),
}} />
If you need anymore information, just comment and thanks in addvanced

"undefined is not an object", need to check if allNotes array is empty. How?

Feel like this is kind of a silly question but I need to only return the allNotes map data if allNotes isn't empty (its an array). This seems like just a simple if/else but really can't figure out how to do this in this context (inside view). Right now, I get the error in the title when nothing is in the array. when it has data everything is fine.
{isOpen &&
<TouchableOpacity onPress={() => updateDrop(prev => !prev)} style={styles.flastListUpdated}>
<View style={{ alignItems: 'center' }}>
<Text style={styles.flastlistItemText2}>{props.noteitem.note}</Text>
</View>
<View style={{ height: 1, width: '100%', backgroundColor: 'lightgrey' }} />
<View>
{allNotes.map((item) => {
return (
<View style={{ flexDirection: 'row', margin: 5 }}>
<View style={styles.perItemBar} />
<Text style={styles.noteTextStyle}>{item}</Text>
</View>
)
})}
<View style={styles.bottomBar}>
<TextInput onChangeText={(text) => { updateNoteStatus(text) }} style={{ flex: 2 }} placeholder='Enter New:' />
<TouchableOpacity onPress={addNote} style={{ flex: 1 }}>
<Text style={{ fontSize: 30 }}>+</Text>
</TouchableOpacity>
</View>
</View>
</TouchableOpacity>
}
</View>
)
}
Again I Know this is something really simple but I can't get the formatting correct. Don't know what the correct method of doing this would be. Thanks!
Could always double check that allNotes is defined like this although it may be better to default allNotes to an empty array and then confirm here that it's what you'd expect.
{isOpen &&
<TouchableOpacity onPress={() => updateDrop(prev => !prev)} style={styles.flastListUpdated}>
<View style={{ alignItems: 'center' }}>
<Text style={styles.flastlistItemText2}>{props.noteitem.note}</Text>
</View>
<View style={{ height: 1, width: '100%', backgroundColor: 'lightgrey' }} />
<View>
{allNotes && allNotes.map(item => (
<View style={{ flexDirection: 'row', margin: 5 }}>
<View style={styles.perItemBar} />
<Text style={styles.noteTextStyle}>{item}</Text>
</View>
)
)}
<View style={styles.bottomBar}>
<TextInput onChangeText={(text) => { updateNoteStatus(text) }} style={{ flex: 2 }} placeholder='Enter New:' />
<TouchableOpacity onPress={addNote} style={{ flex: 1 }}>
<Text style={{ fontSize: 30 }}>+</Text>
</TouchableOpacity>
</View>
</View>
</TouchableOpacity>
}
</View>
)
}

Consuming space in react native

how can I wrap the images and text to use only the right amount of height?
This is what I achieve right now image but it's not what I want because I have a form below that won't show because the text header and the image took up a lot of space.
Home file
<Container>
<ImageBackground style={styles.container} source={require('../../../assets/BG_SignIn.png')}>
<Header />
<Form />
</ImageBackground>
</Container>
Header file
<View style={styles.header}>
<View style={styles.signInHeader}>
<H1>Sign In</H1>
<Text>I don't have an account, yet.</Text>
</View>
<View style={styles.birdHeader}>
<Birds width="100%" height="100%" />
</View>
<Form>
<Item floatingLabel>
<Label>Mobile / Email</Label>
<Input />
</Item>
<Item floatingLabel>
<Label>Password</Label>
<Input secureTextEntry={true} />
</Item>
<Button block rounded style={{ marginTop: 20, backgroundColor: "white" }}>
<Text style={{ color: "#018377", fontSize: 20 }}>Sign In</Text>
</Button>
<Text style={{ margin: 15, }}>Forgot your password?</Text>
</Form>
</View>
const styles = StyleSheet.create({
header: {
display: "flex",
flexDirection: "row",
flex: 1
},
signInHeader: {
flex: 4,
marginTop: 20,
borderWidth: 1,
borderColor: 'red',
},
birdHeader: {
flex: 2,
borderWidth: 1,
borderColor: 'red'
}
})
Just wrap in a view and set flex like you want
<View style={{flex: 0.5}}>
<View style={styles.signInHeader}>
<H1>Sign In</H1>
<Text>I don't have an account, yet.</Text>
</View>
<View style={styles.birdHeader}>
<Birds width="100%" height="100%" />
</View>
</View>
<View style={{flex: 0.5}}>
<Form>
...
</Form>
</View>

How to display Icon in middle of screen in react native

Here, I am displaying "icon="check-decagram" type="MaterialCommunityIcons" in center, but its just coming in center and 20 padding from top. I have to display it middle of the mobile screen. I tried may be I am doing some wrong .Please correct me .
return(
<ImageBackground source={BG} style={styles.imgBG}>
<ScrollView>
<View>
<Header title={title} icon={icon} navigation={navigation} />
</View>
<View style={{ flexDirection: 'column', backgroundColor: '#ffff',}}>
<View style={{
flexDirection:'column', backgroundColor:'#fff',alignItems:'center',paddingTop:20,justifyContent: 'center'}}>
<IconXL icon="check-decagram" type="MaterialCommunityIcons" style={{ color: 'green' }}/>
</View>
<View style={{
flexDirection:'row', backgroundColor:'#ffff',padding:20,flexWrap:'wrap'}}>
<SmallText textColor="grey" text={`v${updateResponse.updateStatusList.currentAppVersion} `}/>
<SmallText textColor="grey" text={`${updateResponse.updateStatusList.desc}`}/>
</View>
</View>
</ScrollView>
</ImageBackground>
)}
// Thanks
try to add two more property height: '100%' and width: '100%' in superview of icon,
like,
<View style={{flexDirection:'column',height: '100%',width: '100%',backgroundColor:'#fff',alignItems:'center',paddingTop:2,justifyContent: 'center'}}>
<IconXL icon="check-decagram" type="MaterialCommunityIcons" style={{ color:'green' }}/>
</View>
Hope this works for you,
Good luck.
You can try something like.
<View style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'blue'
}}>
<Text style={{backgroundColor: 'red'}}>
Your Text
</Text>

Categories