How to specified position from element react-native - react-native

i have a little problem.
I have a tabNavigator in which I have placed an element that must move according to the selected view.
My problem is that I can't specify exactly the position of tabscreen
I can make my element move close to the selection but it is not exactly at the same place
Here is a screenshot to show you what I can do for the moment the green element represents the element that must move.
Screen for this problem
my code :
const [positionX, setPositionX] = useState(new Animated.Value(0));
const animate = (x) => {
console.log("animate");
Animated.timing(positionX, {
toValue: x,
duration: 600,
useNativeDriver: true,
}).start();
};
return (
<NavigationContainer>
<Tab.Navigator
tabBar={(props) => {
console.log(props);
return (
<View
style={{
width: "100%",
height: 50,
backgroundColor: "red",
display: "flex",
flexDirection: "row",
justifyContent: "space-around",
alignItems: "center",
}}
>
<Animated.View
style={{
transform: [{ translateX: positionX }],
position: "absolute",
width: 60,
height: 10,
backgroundColor: "green",
bottom: 50,
left: 0,
}}
></Animated.View>
{routes.map((route, index) => {
return (
<TouchableOpacity
style={{
width: 60,
height: 50,
backgroundColor: "blue",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
onPress={(event) => {
console.log(event.nativeEvent);
animate(
event.nativeEvent.pageX - event.nativeEvent.locationX
);
}}
onLayout={(event) => console.log(event.nativeEvent)}
key={index}
>
<Text>{route.name}</Text>
</TouchableOpacity>
);
})}
</View>
);
}}
initialRouteName="Home"
tabBarShowLabel={false}
screenOptions={{
tabBarShowLabel: false,
headerShown: false,
tabBarStyle: {
backgroundColor: "white",
borderTopColor: "#000",
height: 60,
bottom: 20,
width: "90%",
left: 20,
right: 20,
borderRadius: 15,
position: "absolute",
elevation: 0,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 10,
},
shadowOpacity: 0.53,
shadowRadius: 13.97,
elevation: 21,
},
}}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
<Tab.Screen name="Like" component={LikeScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
I would like my element to be placed at the click for example above Home or Settings... at the click.

Related

ReactNative drawerNavigation custom footer

I have a drawer navigation where I am trying to put a footer on the bottom which would contain additional info (app version and logout link) ..
This is my navigation container:
<NavigationContainer style={styles.drawer}>
<Drawer.Navigator style={styles.drawer} drawerContent={props => <CustomDrawerContent {...props} />}>
<Drawer.Screen name="Home" component={Home}
options={{
drawerIcon: ({ focused, size }) => (
<Image source={require('./assets/icons/sidemenu-icon-account.png')} style={[{ height: 25, width: 25 }]} />
)
}} />
<Drawer.Screen name="LoginScreen" component={LoginScreen}
options={{
drawerIcon: ({ focused, size }) => (
<Image source={require('./assets/icons/sidemenu-icon-account.png')} style={[{ height: 25, width: 25 }]} />
)
}} />
</Drawer.Navigator>
</NavigationContainer>);
And this is the custom content:
function CustomDrawerContent(props) {
return (
<DrawerContentScrollView style={styles.drawer} {...props}>
<View style={styles.logoContainer}>
<Image source={require("./assets/logo.png")} style={{ height: "100%", width: "100%", resizeMode: "contain" }} />
</View>
<SafeAreaView style={styles.container}>
<View style={{flex: 1 }}>
<DrawerItemList {...props} />
</View>
<TouchableOpacity style={{backgroundColor: 'red', flexDirection: 'row', alignItems: 'center'}}>
<Text>Log Out</Text>
</TouchableOpacity>
</SafeAreaView>
</DrawerContentScrollView>
);
}
How can I push the log out link to be fixed at the bottom?
Styles:
const styles = StyleSheet.create({
img: {
height: 40,
width: 40,
marginTop: 6,
justifyContent: 'center',
textAlignVertical: 'center',
},
logout : {
backgroundColor: 'red' ,
bottom: 0,
position: 'absolute'
},
logoContainer: {
height: 140,
width: "80%",
marginTop: 20,
marginBottom: 20,
alignSelf: "center",
},
drawer: {
backgroundColor: 'yellow',
flex:1
},
labelBottom : {
position: 'relative',
bottom:0
},
redBottom: {
},
scrollView: {
backgroundColor: Colors.lighter,
},
engine: {
position: 'absolute',
right: 0,
},
body: {
backgroundColor: Colors.red,
},
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
color: Colors.black,
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
color: Colors.dark,
},
highlight: {
fontWeight: '700',
},
footer: {
color: Colors.dark,
fontSize: 12,
fontWeight: '600',
padding: 4,
paddingRight: 12,
textAlign: 'right',
},
Instead of style prop, you may use contentContainerStyle:
<DrawerContentScrollView
...
contentContainerStyle={styles.drawerContentContainer}
/>
while the style is something like:
drawerContentContainer: {justifyContent: 'space-between', flex: 1},
You can use a marginTop: 'auto' style for TouchableOpacity, also use the contentContainerStyle for scrollviews
function CustomDrawerContent(props) {
return (
<DrawerContentScrollView contentContainerStyle={styles.drawer} {...props}>
<View style={styles.logoContainer}>
<Image source={require("./assets/logo.png")} style={{ height: "100%", width: "100%", resizeMode: "contain" }} />
</View>
<SafeAreaView style={{flex:1}}>
<View>
<DrawerItemList {...props} />
</View>
<View style={{ marginTop: 'auto' }}>
<TouchableOpacity
style={{
backgroundColor: 'red',
flexDirection: 'row',
}}>
<Text>Log Out</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
</DrawerContentScrollView>
);
}
I solved this by wrapping all the contents of my DrawerComponent inside a View element and then adding height: '100%' in the style prop of the root View element.
And finally adding marginTop: 'auto' will push the FooterComponent at the bottom (or you can use {position: 'absolute', bottom: 0} for style prop of FooterComponent).
<View style={{height: '100%'}}>
<HeaderComponent />
<DrawerItems {...props} />
<View style={{marginTop: 'auto'}}>
<FooterComponent />
</View>
</View>

Component won't stay wrapped within bounds (React Native)

I am trying to make my own tab navigation like Instagram has instagram example. I noticed that the items within the footer view I made does not stay within the bounds and moves to the top left of the screen. Images shown - What I am trying to achieve What happens frequently
Here is the most important part of my code. I have done inline styles temporarily to try and figure out the issue. Here is the part where the issue lays <View style = {{ width: Dimensions.get('window').width, backgroundColor: '#fff', height: 80}} <TouchableOpacity onPress = {() => this.props.navigation.navigate('Profile')} style = {{justifyContent: 'flex-end'}}>
<Text style = {{justifyContent: 'flex-end'}}> Profile </Text>
</TouchableOpacity> </View>-
render() {
return (
<MapView style = {[style.container, style.map]}
region = {this.state.initialPosition}>
<MapView.Marker coordinate = {this.state.markerPosition}>
<View style = {style.radius}>
<View style = {style.marker}/>
</View>
</MapView.Marker>
<View style = {{ width: Dimensions.get('window').width, backgroundColor: '#fff', height: 80}} >
<TouchableOpacity onPress = {() => this.props.navigation.navigate('Profile')} style = {{justifyContent: 'flex-end'}}>
<Text style = {{justifyContent: 'flex-end'}}> Profile </Text>
</TouchableOpacity>
</View>
</MapView>
);
}
}
const style = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'flex-end',
//alignItems: 'center',
},
text: {
color: '#fff'
},
map: {
left: 0,
right: 0,
top: 0,
bottom: 0,
position: 'absolute'
},
radius:{
height: 50,
width: 50,
borderRadius: 50 / 2,
overflow: 'hidden',
backgroundColor: 'rgba(1,213,106,0.3)',
borderWidth: 1,
borderColor: 'rgba(1,213,106,0.3)',
alignItems:'center',
justifyContent: 'center'
},
marker: {
height: 20,
width: 20,
borderWidth: 3,
borderColor: '#fff',
borderRadius: 20 / 2,
borderWidth: 3,
overflow: 'hidden',
backgroundColor: '#01D56A'
},
menuSection: {
backgroundColor: 'rgba(255, 255, 255, 0.7)',
width: Dimensions.get('window').width,
height: Dimensions.get('window').height/3,
justifyContent: 'flex-end',
alignItems: 'center'
},
icon:{
width: 50,
height: 50,
backgroundColor: 'black'
}
})

TextInput in absolute positioned LinearGradient doesnot focus

I have a component with 2 LinearGradient views, both of them with absolute position and one with TextInput. For this setting, TextInput never gains focus in Android.
Code:
class SearchScreen extends Component {
render() {
return (
<View style={{ flex: 1 }}>
<LinearGradient
colors={['blue', 'red']}
style={{
height: 80,
width: '100%',
position: 'absolute',
zIndex: 10,
elevation: 10,
top: 0,
left: 0,
}}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
>
<TextInput
style={{
backgroundColor: 'white',
height: 50,
paddingLeft: 15,
marginTop: 10,
marginBottom: 10,
marginRight: 20,
marginLeft: 20,
borderWidth: 0,
}}
placeholder={'search placeholder'}
onFocus={() => { console.log('onFocus: '); }}
onChangeText={(text) => { console.log('enter text: ', text); }}
onEndEditing={() => { console.log('endEditing: '); }}
/>
</LinearGradient>
<LinearGradient
colors={['red', 'blue']}
style={{
height: 150,
width: '100%',
position: 'absolute',
zIndex: 5,
elevation: 5,
}}
>
</LinearGradient>
</View >
);
}
}
export default SearchScreen;
React Native: 0.55.2
react-native-linear-gradient: 2.4.0
I found the problem is with the 2 absolute positioned LinearGradient View with Text Input. If I remove the one of the LinearGradient, the TextInput works fine as it should.
I've tried providing zIndex to the TextInput too, it doesn't work.
Thanks.
Seems like a bug in the zIndex for android, as it works fine for IOS.
You can use it the following way as a workaround by nesting of linear gradients so that there is no conflict for the overlay element that renders.
<LinearGradient
colors={['red', 'blue']}
style={{
height: 150,
width: '100%',
position: 'absolute',
zIndex: 5,
elevation: 5,
}}
>
<LinearGradient
colors={['blue', 'red']}
style={{
height: 80,
width: '100%',
position: 'absolute',
zIndex: 10,
elevation: 10,
top: 0,
left: 0,
}}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
>
<TextInput
style={{
backgroundColor: 'white',
height: 50,
paddingLeft: 15,
marginTop: 10,
marginBottom: 10,
marginRight: 20,
marginLeft: 20,
borderWidth: 0,
}}
placeholder={'search placeholder'}
onFocus={() => { console.log('onFocus: '); }}
onChangeText={(text) => { console.log('enter text: ', text); }}
onEndEditing={() => { console.log('endEditing: '); }}
/>
</LinearGradient>
</LinearGradient>

text Align :'right' doesn't work for placeholder when multiline is true

In my code i have 2 textInputs, one has one line and the other has multiple lines, the input is arabic so i have to enable textAlign: 'right',
my problem is when i set multilines to true, the placeholder text remains on the left side of the text input,
any idea how to solve this?
my code is the following:
View:
<View style={{ position: 'relative' }}>
<TextInput
style={forms.textInput}
value={this.state.telephone}
placeholder={'رقم هاتفك'}
placeholderTextColor={'rgba(0,0,0,0.6)'}
onChangeText={(val) => this.setState({telephone: val}) } />
<Icon name="android-phone-portrait" size={27} color="rgba(0,0,0,0.6)" style={{ position: 'absolute', top: 10, right: 24 }}/>
</View>
<View style={{ position: 'relative' }}>
<TextInput
style={[forms.textInput,{height: 120}]}
multiline={true}
value={this.state.desc}
numberOfLines={4}
placeholder={'اقتراحك'}
placeholderTextColor={'rgba(0,0,0,0.6)'}
onChangeText={(val) => this.setState({desc: val}) }/>
<Icon name="ios-help-outline" size={27} color="rgba(0,0,0,0.6)" style={{ position: 'absolute', top: 10, right: 24 }}/>
</View>
Style:
textInput: {
height: 40,
borderColor: 'rgba(0, 0, 0, 0.4)',
borderWidth: 2,
margin: 15,
marginTop: 5,
backgroundColor: '#fff',
color: 'rgba(0, 0, 0, 0.9)',
paddingRight: 40,
textAlign :'right'
},
______________________*******________________________
______________________*******________________________
I have actually made a pull request for this which has been accepted and will be in the 0.29.0 release of react-native.
My fix was to add this line
_placeholderView.textAlignment = _textView.textAlignment;
to react-native/Libraries/Text/RCTTextView.m
Inside the updatePlaceholder function (right before [self insertSubview:_placeholderView belowSubview:_textView];)
GitHub Commit

React-Native: how to disable TouchableHighlight when scrolling during animation?

I need to disable a button when scrolling using Animated.ScrollView in react-native.
I am trying to apply something like:
disabled={this.state.scrollY._value <= 30 ? false : true}
in the props of the TouchableHighlight.
From what I have learned, it is not possible to apply the value: this.state.scrollY._value directly into the 'disabled' prop of the TouchableHighlight. However I really dont know how to proceed -.-
I am really grateful for any help.
my button is in the following format:
<Animated.View>
<TouchableHighlight>
<Icon />
</TouchableHighlight>
</Animated.View>
here is the complete code:
<Animated.View style={{
position: 'absolute',
elevation: 5,
justifyContent: 'center',
flex: 1,
height: 100,
width: 100,
opacity: 1,
left: SCREEN_WIDTH / 2 - SIZE / 2,
top: 120,
opacity: buttonTopDisappearance,
}}>
<TouchableHighlight
onPress={() => {
this.toggleView(playBack);
if (!playBack) {
this.setState({ playBack: true })
} else {
this.setState({ playBack: false })
}
}}
underlayColor="#2882D8"
disabled={this.state.scrollY._value <= 30 ? false : true}
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
width: null,
height: null,
borderRadius: SIZE / 2,
backgroundColor: '#48A2F8',
position: 'relative',
elevation: 6,
}}
>
<IconFontAwesome name="plus" size={24} color="#F8F8F8" />
</TouchableHighlight>
</Animated.View>