react native list without transparency - reactjs

I got the following problem: I want to implement a location search bar with the google maps places api to generate results. Everything is working, but the listview(which's position prop is set to absolute) seems to be transparent.
i already tried to set the containers opacity to 1 but that didnt helped. can someone tell me what i need to change to make to underlaying test-text not visible in the container?
my code:
locationPicker:
<View style={styles.modalContainer}>
<SafeAreaView style={styles.safeArea}>
<View style={styles.searchContainer}>
<LocationSearchBar/>
</View>
</SafeAreaView>
<View style={styles.modalContent}>
<Text>test</Text>
</View>
</View>
searchContainer: {
alignItems: "center",
justifyContent: "center",
minHeight: 60,
paddingHorizontal: 16,
paddingVertical: 10,
backgroundColor: theme.colors.screen.alter
}
locationSearchBar:
<React.Fragment>
<TextInput
autoCorrect={false}
onChangeText={handleTextChange}
value={inputValue}
label={<Icon name={"search"} />}
placeholder={"Search location..."}
/>
<ScrollView style={styles.autoCompleteResultList}>
{locationResults.map((el, i) => (
<AutoCompleteItem
{...el}
fetchDetails={fetchDetails}
key={String(i)}
/>
))}
</ScrollView>
</React.Fragment>
AutoCompleteItem:
<View style={styles.autoCompleteItemContainer}>
<RkText rkType={"primary2"}>{this.props.structured_formatting.main_text}</RkText>
<RkText rkType={"primary1"}>{this.props.structured_formatting.secondary_text}</RkText>
</View>
autoCompleteItemContainer: {
backgroundColor: "red",
paddingHorizontal: 5,
paddingVertical: 5
},
autoCompleteResultList: {
maxHeight: 200,
position: "absolute",
backgroundColor: theme.colors.screen.alter,
width: "100%",
top: 55
}
cheers!

I think it's not a background-color or opacity problem.
It seems overlay problem of your position:absolute and default views
test is normal or default one so it has highest priority to come over any position:absolute views.
hence, test is above the results.
You'll need to change this position and make result above the test.
so do this by zIndex.
autoCompleteResultList: {
maxHeight: 200,
position: "absolute",
backgroundColor: theme.colors.screen.alter,
width: "100%",
top: 55,
zIndex:1 // highest number of zIndex in your current screen if you have other zIndex
}

Related

How to achieve Font Awesome stack icons feature in react native

Achieving Stack/Overlap Icons using React native.
I am trying to achieve something like this in react native:
https://fontawesome.com/how-to-use/on-the-web/styling/stacking-icons
how to achieve this?
You can achieve this by doing it like this. Using width and height helps you keep the view in place and aligning everything to the center so it looks nice like stacked icons.
<View style={{
position:"relative",
justifyContent:'center',
alignItems:"center",
width:40,
height:40
}}>
<Icon name="circle" size={34} color={"black"} />
<Icon name="flag" size={20} color={"white"} style={{position: 'absolute', zIndex: 99}} />
</View>
https://snack.expo.io/HkxWerHBr
Output:
In this Example I stacked the FontAwesome Icon "square" and "home". To stack them, you need a parent view with position: 'relative'. Then you can apply position: 'absolute'and a zIndex to the icon which should be on top of the other one. Afterwards you can position the icon for example with the top/left style property.
Code:
<View style={{position: 'relative'}}>
<Icon name="square" size={24} color={"black"} />
<Icon
name="home"
size={24}
color={"white"}
style={{position: 'absolute', zIndex: 99, left: 0, top: 0}} />
</View>
Demo:
https://snack.expo.io/rkHnZJrrH
Was able to achieve like this with react native elements [ not sure if they use zIndex internally]
render() {
return (
<View style={styles.container}>
<View
style={{
position: 'relative',
height: 64,
width: 64,
justifyContent: 'center',
alignItems: 'center',
}}>
<Icon type="font-awesome" name="square" size={64} />
<Icon
type="font-awesome"
name="twitter"
color="white"
size={32}
containerStyle={{ position: 'absolute' }}
/>
</View>
</View>
);
}
And the container style would be
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
}
snack repo:
https://snack.expo.io/#roach_iam/vigorous-blueberries

Image background in scroll view not working React Native

I am new in react native and I have to design a screen and when list going longer I realised my scroll view is not working here is below my code please share suggestion...Thanks!
<View style={{flex:1}}>
<ActionBar
containerStyle={{height:60,alignItems: 'center'}}
backgroundColor={'#fff'}
title={'Select Categories'}
titleStyle={styles.pageTitle}
onLeftPress={() => goBack()}
leftIconContainerStyle={{marginTop:22}}
leftIconName={'back'}
leftIconImageStyle={{backgroundColor:'#333',height:18,width:18}}
/>
<Image source={require('../images/bg-login.jpg')}
style={{position:'absolute',left:0,right:0,top:0,bottom:0}} />
<ScrollView style={{backgroundColor:'#00000000',position:'absolute',left:0,right:0,top:0,bottom:0}} >
{views}
</ScrollView>
<View style={styles.footerSec}>
<TouchableOpacity style={styles.nextBtn}
onPress={()=> {this.props.navigation.navigate('Tutorials',{tutId:this.state.selectedCats})}}>
<Text style={[styles.btnText, styles.priceText]}>Next</Text>
</TouchableOpacity>
</View>
</View>
Here is my list code:
<TouchableOpacity key={itemData[j]._id}
onPress = {() => {
activeItem ? this.removeCat(itemData[j]._id) : this.insertCat(itemData[j]._id)
}}>
<View style={{position:'relative'}}>
<LinearGradient colors={activeItem ? ['#cb5fb1', '#f874d8', '#f98bde'] :['#ffb6cf','#ffb6cf','#ffb6cf'] } style={{
position: 'absolute',
alignItems: 'center',
justifyContent:'center',
backgroundColor: '#f673d7',
width: armSize,
height: armSize,
borderRadius: (armSize) / 2,
top: topp,
left: leftp,
}}>
<Text style={{
color: '#fff',
alignSelf:'center',
fontSize: RandomNumber,
fontWeight: '600',
}}>
{itemData[j].name}
</Text>
</LinearGradient>
</View>
</TouchableOpacity>
I designed below screen but the scroll view bounce and come up on same position...I think this is because of child position style but it's required for the circle in row. I can't scroll for below circles that's the issue.
You could use normal Image to put a background image using position='absolute' and setting background color opacity of ScrollView to #00000000 which means that will be transparent
Example
<Image
source={require('../images/bg-login.jpg')}
style={{position:'absolute',
left:0,
right:0,
top:0,
bottom:0}} />
<ScrollView
style={{backgroundColor:'#00000000',
position:'absolute',
left:0,
right:0,
top:0,
bottom:0}} >
<View>
<Text>Some content</Text>
</View>
</ScrollView>
For the scroll view issues I used below code and it's working fine everywhere
<ScrollView contentContainerStyle={{ paddingBottom: 120 }}>
---code---
</ScrollView>

How to force react native content to ignore keyboard?

I have tried using both KeyboardAvoidingView and ScrollView to prevent my content from being squished (pushed up) when the keyboard is present. I have tried using padding, height, and position for my behavior but nothing is working. Can someone please tell me how I can force my content to ignore the keyboard and not get pushed up??
return (
<View style={{height: '100%', backgroundColor: '#D6D6D6', position: 'relative'}}>
<View style={styles.wrapper}>
<View style={{height:'100%', borderRadius: 7}}>
<View style={styles.container}>
<ScrollView style={{borderRadius: 7}}
horizontal
showsHorizontalScrollIndicator={false}
scrollEventThrottle={10}
pagingEnabled
onScroll={
Animated.event(
[{nativeEvent: {contentOffset: {x: this.animVal}}}]
)
}
>
{imageArray}
</ScrollView>
<View style={styles.listViewContainer}>
<TouchableOpacity style={styles.listView} onPress={() => Actions.pop()}>
<View style={{flex: 1, flexBasis: 22}}>{listIcon}</View>
<View style={{flex: 2, flexBasis: 57}}><Text style={{color: '#fff'}}>List View</Text></View>
</TouchableOpacity>
</View>
<View style={styles.circleContainer}>
{circleArray}
</View>
</View>
<View style={styles.productsSection}>
<Text style={styles.title}>{prodDesc}</Text>
<Text style={styles.desc}>{prodBrand}</Text>
<Text style={styles.desc}>Item: {prodId || ''}</Text>
<Text style={[styles.desc, {marginBottom: 15}]}>Category: {prodCat}</Text>
<Table borderStyle={{borderWidth: 0}}>
<Rows data={rows}/>
</Table>
</View>
<View style={styles.bodyFooter}>
<QuantityCounter style={{width: '100%', display: 'block', marginRight: 20}} data={{productId: prodId}} />
</View>
</View>
</View>
<View style={styles.footer}>
<View style={styles.cartContainer}>
{cartIcon}
<Text style={{color: '#3A3A3A', fontSize: 14}}>18 items</Text>
</View>
<TouchableOpacity style={styles.viewCartButtonContainer} onPress={() => this.cartRedirect() }>
<Text style={{color: '#fff', fontSize: 15, marginTop: '5%'}}>View Cart</Text>
</TouchableOpacity>
</View>
<Header/>
</View >
);
here are my main styles for this:
var styles = StyleSheet.create({
wrapper: {
backgroundColor: '#E6E6E6',
marginVertical: 15,
marginHorizontal: 10,
borderRadius: 7,
elevation: 3,
maxHeight: '80%',
flexShrink: 1,
zIndex: 0,
marginTop: 75
},
container: {
flex: 1.7,
justifyContent: 'space-between',
alignItems: 'center',
height: '50%',
borderRadius: 7
},
footer: {
justifyContent:'space-between',
alignItems: 'center',
height: '10%',
backgroundColor: '#E6E6E6',
paddingVertical: 15,
paddingHorizontal: 17,
flexDirection: 'row',
borderStyle: 'solid',
borderTopColor: '#8E8E93',
borderTopWidth: 1
},
cartContainer: {
flexDirection: 'row',
width: '35%'
},
viewCartButtonContainer: {
backgroundColor: '#356FAF',
height: '90%',
width: '45%',
padding: 20,
alignItems: 'center',
justifyContent: 'center',
borderRadius: 3
},
bodyFooter: {
backgroundColor: '#F6F6F6',
justifyContent: 'center',
flex: 0.45,
borderTopColor: '#D6D6D6',
borderTopWidth: 1,
borderStyle: 'solid',
borderBottomRightRadius: 7,
borderBottomLeftRadius: 7
},
circleContainer: {
position: 'absolute',
zIndex: 2,
bottom: 10,
left: 10,
flexDirection: 'row',
},
listViewContainer: {
position: 'absolute',
zIndex: 10,
top: 0,
right: 0,
justifyContent: 'center'
},
listView: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
borderTopRightRadius: 3,
backgroundColor: '#000',
paddingVertical: 5,
paddingHorizontal: 10
},
What it looks like without the keyboard:
What it looks like with the keyboard:
Handling View behavior when toggling a keyboard can be a tricky thing in React Native. There are multiple possible solutions to questions like this, but in this case the solution was this:
Instead of using style={{height:'100%'}} on your components that get pushed up, try using Dimensions:
import {Dimensions} from 'react-native';
const { height } = Dimensions.get('window');
and specify style={{ height }} in the right components.
Another thing that might be worth a try if someone else stumbles on this question:
React Native for Android has some default settings defined in the Android manifest. If you are not using Expo (or CRNA), you can change the behavior of the keyboard in AndroidManifest.xml by changing the windowSoftInputMode rule.
Try changing android:windowSoftInputMode="adjustResize" to android:windowSoftInputMode="adjustPan" or to android:windowSoftInputMode="adjustNothing". You can try to play around with some other options (See here) if this doesn't give you the desired effect.
You should use try behavior as "none" for android and if you don't want to getting small, you can set android:windowSoftInputMode="adjustPan" in manifest file.
and if still face any error checkout react-native-keyboard-aware-scrollview
here on npm.
I went through a similar problem and solved it by changing
android:windowSoftInputMode="adjustPanā€¯
In android manifest.
Also clean and rebuild. This might work
remove the position absolute it will works just fine trust me
for some cases if you want keep defualt manifest
you can move your elements inside a Scrollview it may help.
issue solved for me in this way

creating partially transparent background layout in react native

I am using react native 0.49 and here is what I want to achieve:
so far this is what I did:
render() {
return (
<View style={{flex: 1}}>
<View style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center'}}>
<SearchHeader /> // search input component
<View style={{padding: 5}}>
<TouchableOpacity style={{padding: 5}} onPress={this.btnPressed}> // icon more
<Image source={require('../../assets/iconMore/iconMore.png')}/>
</TouchableOpacity>
</View>
</View>
<TabBarMain navigation={this.props.navigation}/> // tab navigator
{
this.state.showView
?
<View style={popoverStyle}>
<Text>View is showing</Text>
</View>
:
null
}
</View>
);
}
btnPressed = () => {
this.setState({
showView: !this.state.showView
});
}
I am trying to make that transparent background behind the view but Im failing to do so. Also, that triangle arrow pointer right underneath the icon (icon more). Im not sure if my code/component structure is correct, also the dark layout supposed to dismiss the view when pressed (pressing outside the view).
UPDATE
I added a view according to #sfratini answer.
showShadowLayer = () => {
if (this.state.showView){
return {
position: 'absolute',
top: 0, bottom: 0, left: 0, right: 0,
backgroundColor: "rgb(0,0,0)",
opacity: 0.5,
zIndex: 1000
}
} else {
return {
flex: 1
}
}
}
render() {
return (
<View style={{flex: 1}}>
<StatusBarView style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center'}}>
<SearchHeader />
<View style={{padding: 5}}>
<TouchableOpacity style={{padding: 5}} onPress={this.btnPressed}>
<Image
source={require('../../assets/iconMore/iconMore.png')}
/>
</TouchableOpacity>
</View>
</StatusBarView>
<TabBarMain navigation={this.props.navigation}/>
<View style={this.showShadowLayer()}/> // <-- added the partial transparent view here
{
this.state.showView
?
<View style={popoverStyle}>
<Text>View is showing</Text>
</View>
:
null
}
</View>
);
}
const popoverStyle = { // style for the custom popover
borderStyle: 'solid',
position: 'absolute',
backgroundColor: 'white',
borderColor: 'black',
elevation: 5,
height: SCREEN_HEIGHT,
width: SCREEN_WIDTH - 40,
alignSelf: 'flex-end',
marginTop: 60,
//for ios
shadowColor: 'black',
shadowOpacity: 0.3,
shadowOffset: { width: 3, height: 3 },
shadowRadius: 4,
}
But now I cannot interact with this view. How to dismiss it when pressed outside the view!
Just add a "modal view" behind your drawer. Something like this should do:
<View style={{
position: 'absolute',
top: 0, bottom: 0, left: 0, right: 0,
backgroundColor: rgba(255,255,255,0.5)
}}/>
The 4th value is the opacity
Edit:
Add it after here:
<View style={this.showShadowLayer()}/> // add here
{
this.state.showView
?
<View style={popoverStyle}>
<Text>View is showing</Text>
</View>
:
null
}
RN handles the zIndex by checking in which order you add the views in the render.
As you saw after a couple of testing, render can only have one parent so I am wrapping everything in another view.

How to horizontally center a component while there are other components in the same row?

I'm trying to mimic a stack navigation header like below:
where the title is perfectly centered while there's a return button in the same row on the left.
I have tried to use justifyContent: 'space-between' with an empty View on the right side but the title will be off center to the right a bit. How should I approach this?
my renderHeader function:
_renderHeader = () => {
return (
<View style={styles.headerAbsolute}>
<View style={styles.bar}>
<ButtonBack
text={"Resumes"}
onPress={() => this._onNavBackHandler()}
/>
{true ? (
<Text style={styles.headingFixed}>{this.state.title}</Text>
) : ( null )}
<View/>
</View>
</View>
)
}
These are the styles:
bar: {
height: 55,
flexDirection: "row",
alignItems: 'flex-end',
justifyContent: 'space-between',
paddingHorizontal: 10,
paddingBottom: 5,
},
headingFixed: {
fontSize: TITLE_TERTIARY,
fontWeight: 'bold',
color: COLOR_DARK_SECONDARY,
backgroundColor: 'transparent',
},
I will make use of Flex here.
Please note that i used borderWidth in the below example only for reference to show how it looks.
I will have flexDirection as row and i will give a flex: 1 to all the views inside
App.js
import React, { Component } from 'react';
import {
View,
Text
}
from 'react-native';
class App extends Component{
render(){
return(
<View>
<View style={styles.navBar}>
<View style={styles.itemStyle}>
<Text style={{fontSize: 18, color: 'blue'}}>Resumes</Text>
</View>
<View style={styles.itemStyle}>
<Text style={{fontSize: 20, color: 'blue'}}>Settings</Text>
</View>
<View style={styles.itemStyle}></View>
</View>
</View>
)
}
}
const styles = {
navBar: {
marginTop: 42,
height: 36,
flexDirection: 'row',
alignItems: 'center'
},
itemStyle: {
flex: 1,
height: 36,
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1
}
}
export default App;
You can play around in the inside views. Move the buttonBack inside one of the child views.
I can think of two ways to accomplish this, but neither seems quite ideal.
The first way is using a transparent element with fixed width and justifyContent: 'space-between', as you indicated:
<View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<Text style={{width: 80}}>left</Text>
<Text>center</Text>
<Text style={{width: 80, color: 'transparent'}}>right</Text>
</View>
Setting a fixed width to the elements on each side will cause the middle element to center horizontally.
An alternative approach is using absolute styling. Using percentages with left and right requires React Native >= 0.42.
<View>
<Text>Left</Text>
<Text style={{position: 'absolute', width: 50, left: '50%', marginLeft: -25}}>Center</Text>
</View>

Resources