ScrollView removing TextInput keyboard in React Native - react-native

I am using TextInput with custom clear icon to clear text. As I need to keep multiple TextInputs in screen, I used a ScrollView:
import React, {Component} from 'react';
import {
View,
Text,
ScrollView,
StyleSheet,
Image,
TouchableOpacity,
TextInput,
} from 'react-native';
export default class SuccessScreen extends Component {
constructor(props) {
super(props);
this.state = {};
}
handleRightClick() {
console.log('handleRightClick');
}
render() {
return (
<ScrollView>
<View style={styles.SectionStyle}>
<TextInput style={styles.input} />
<TouchableOpacity
style={styles.ImageStyle}
onPress={this.handleRightClick}>
<Image source={require('../../images/cross_icon.png')} />
</TouchableOpacity>
</View>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
input: {
flex: 1,
borderColor: '#000000',
borderBottomWidth: 1,
height: 40,
fontSize: 15,
color: '#000000',
},
SectionStyle: {
flexDirection: 'row',
minWidth: '100%',
height: 40,
},
ImageStyle: {
height: 25,
width: 25,
marginLeft: -25,
alignContent: 'center',
resizeMode: 'stretch',
alignItems: 'center',
},
});
Without the ScrollView, handleRightClick is called, but when I use the ScrollView, it just dismiss keyboard and don't call handleRightClick.

The ScrollView has a prop keyboardShouldPersistTaps. You should set it to 'handled' so your TouchableOpacity will handle the press instead of the ScrollView.
<ScrollView keyboardShouldPersistTaps='handled'>
// ...
</ScrollView>

Related

react native shows nothing if I use touchablewithoutfeedback

I create a form but if I add touchablewithoutfeedback then it shows nothing more. If I use View its show but why?
import { StatusBar } from 'expo-status-bar';
import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, ImageBackground, TextInput, Dimensions, KeyboardAvoidingView } from 'react-native';
import { TouchableOpacity, ScrollView, TouchableWithoutFeedback } from 'react-native-gesture-handler';
import { Ionicons } from '#expo/vector-icons';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
const createRoom = () => {
return (
<TouchableWithoutFeedback style={{flex: 1,alignItems: 'center', justifyContent: 'center'}}>
<KeyboardAvoidingView behavior="position">
<View style={{backgroundColor: 'red', width: width * 0.8, padding: 20, borderRadius: 8, elevation: 2}}>
<View style={{marginTop: 20, marginBottom: 20}}>
<TextInput placeholder="Username" style={styles.input} />
</View>
<View style={styles.locationContainer}>
<TouchableOpacity>
<Text>geolocation</Text>
</TouchableOpacity>
<View>
<Text>Test</Text>
</View>
</View>
<TouchableOpacity style={styles.button}>
<Text>Gruppe erstellen</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</TouchableWithoutFeedback>
)
};
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff'
},
input: {
padding: 4,
backgroundColor: '#fff',
},
image: {
height: 150,
borderRadius: 12,
},
locationContainer: {
flexDirection: 'row',
justifyContent: 'space-between'
},
button: {
color: '#fff',
justifyContent: 'center',
alignItems: 'center',
padding: 10
}
});
export default createRoom;
i am very thankful for your help. I dont know the issue.......................................................................................................................................
You can change the TouchableWithoutFeedback import from react-native-gesture-handler to react-native.
import {StyleSheet, Text, View, ImageBackground, TextInput, Dimensions, KeyboardAvoidingView, TouchableOpacity, ScrollView, TouchableWithoutFeedback} from 'react-native';
Or you can go for a new component Pressable

React Native: React Navigation using reusable component

I'am new in React Native & I'am trying to create separated Button component file (reusable component), and when I press the button it will navigate to another page (react-navigation). Below is my code:
GlobalButton.js
import React from 'react'
import { StyleSheet, TouchableOpacity, Text} from 'react-native'
import { useNavigation, NavigationContainer } from '#react-navigation/native';
const GlobalButton = (props, {screenName}) => {
const navigation = useNavigation();
return
<TouchableOpacity style={[styles.btn, props.style]} onPress= {() => navigation.navigate(screenName)}>
{props.children}
</TouchableOpacity>
}
const styles = StyleSheet.create({
btn: {
alignItems: 'center',
textAlign: 'center',
borderRadius: 25,
height: 50,
}
})
export default GlobalButton;
LoginPage.js
import React from 'react'
import { StyleSheet, Text, View, Image, TextInput, Button} from 'react-native'
import ButtonLogin from '../components/GlobalButton'
// import { useNavigation, NavigationContainer } from '#react-navigation/native';
export default function LoginPage() {
return (
<View style={styles.penampung}>
<Image source= {require('../assets/beetle.png')} style={styles.gambar}/>
<TextInput style={styles.textField} placeholder='username' />
<TextInput style={styles.textField} placeholder='password' secureTextEntry={true} />
<ButtonLogin style={styles.btnStyle} screenName="MainPage"><Text style={styles.text}>LOGIN</Text></ButtonLogin>
</View>
)
}
const styles = StyleSheet.create({
penampung: {
flex: 1,
alignItems: 'center',
backgroundColor: '#00688B',
justifyContent: 'center'
},
gambar: {
height: 100,
width: 100,
},
textField: {
marginTop: 25,
backgroundColor: '#cafafe',
borderRadius: 25,
width: '80%',
height: 50,
paddingLeft: 20
},
btnStyle: {
padding: 10,
position: 'absolute',
bottom: 20,
backgroundColor: "#fc4445",
width: '80%'
},
text:{
fontSize: 20,
fontWeight: 'bold',
color: 'white'
}
})
What I'am expecting is that when I click the login button it should navigate to the MainPage.js, but instead it gives error message ->
Error: You need to specify name or key when calling navigate with an object as the argument.
Please anyone help me in this matter, Thanks...
You should do like below as screenName is part of your props,
<TouchableOpacity style={[styles.btn, props.style]} onPress= {() => navigation.navigate(props.screenName)}>

How do I make TouchableOpacity only clickable within its shape on mobile?

On web, shaping a TouchableOpacity makes it so only the shape is clickable, however on mobile the entire "box" surrounding the shape is clickable. Is there any way at all to make it so just the shape is clickable?
I have tried shaping the view and setting the style on both View and TouchableOpacity to overflow: 'hidden' but this also fails to contain the area which is touchable.
import React, { Component } from 'react';
import { StyleSheet, TouchableOpacity, Text, View } from 'react-native';
export default class App extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
onPress = () => {
this.setState({
count: this.state.count + 1,
});
};
render() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.button} onPress={this.onPress}>
<Text> Touch Here </Text>
</TouchableOpacity>
<View style={[styles.countContainer]}>
<Text style={[styles.countText]}>
{this.state.count !== 0 ? this.state.count : null}
</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingHorizontal: 10,
overflow: 'hidden',
},
button: {
alignItems: 'center',
backgroundColor: '#DDDDDD',
padding: 10,
borderRadius: 640,
height: 320,
width: 320,
overflow: 'hidden',
},
countContainer: {
alignItems: 'center',
padding: 10,
},
countText: {
color: '#FF00FF',
},
});
Here's a snack example of my problem

react-native flexbox children inner elements

Using react-native. How to make text show inside (and not bellow) the background image?
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Image,
TextInput,
TouchableOpacity,
AsyncStorage,
} from 'react-native';
import { Navigator } from 'react-native-deprecated-custom-components';
export default class Test extends Component {
render() {
return (
<View style={styles.container}>
<Image
source={require('../img/example.jpg')}
style={styles.backgroundImage}
blurRadius={1} />
<View style={styles.content}>
<Text style={styles.logo}> Example Text </Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
backgroundImage: {
flex: 1,
alignSelf: 'stretch',
width: null,
justifyContent: 'center',
},
content: {
alignItems: 'center',
},
logo: {
color: 'white',
fontSize: 40,
fontStyle: 'italic',
fontWeight: 'bold',
textShadowColor: '#252525',
textShadowOffset: { width: 2, height: 2 },
textShadowRadius: 15,
marginBottom: 20,
}
});
As you can see, in the example above, the Text appears outside the backgroundimage... Maybe is something with the flexbox but im not sure...
try with:
<Image
source={require('../img/example.jpg')}
style={styles.backgroundImage}
blurRadius={1}>
<View style={styles.content}>
<Text style={styles.logo}> Example Text </Text>
</View>
</Image>

Text wrap with chevron on right in React Native ListView item renderer

I am trying to have a list view show up that looks similar to this. The problem I am trying to solve is regarding word wrapping of the label. I do have it working with the code below, but it feels like a hack and doesn't work with device rotation. There has to be a way to do it without using Dimensions and styling.
Here is what I have.
import React, { Component } from 'react';
import {
StyleSheet,
Dimensions,
TouchableOpacity,
Text,
View
} from 'react-native';
import Moment from 'moment'
import Icon from 'react-native-vector-icons/FontAwesome';
class ProjectListItemRenderer extends Component {
componentDidMount() {
//alert(Dimensions.get('window').height)
}
render() {
return (
<View style={styles.projectRow}>
<View style={{width: Dimensions.get('window').width - 50}}>
<Text style={styles.itemName}>{this.props.name}</Text>
<Text style={styles.itemDetails}>{`${Moment(this.props.lastUpdated).fromNow()}`}</Text>
</View>
<View style={styles.moreContainer}>
<Icon name="chevron-right" size={15} style={styles.moreIcon} />
</View>
</View>
);
}
}
const styles = StyleSheet.create({
projectRow: {
flexDirection: 'row',
justifyContent: 'flex-start',
padding: 15,
},
itemName: {
fontSize: 18,
color: '#4A90E2',
},
itemDetails: {
fontSize: 12,
color: '#BBBBBB',
},
moreContainer: {
justifyContent: 'center',
alignItems: 'center'
},
moreIcon: {
color: "#d6d7da"
}
});
module.exports = ProjectListItemRenderer;
The other option I tried was absolute positioning, with the label being 20px from the right, and then absolute positioning the chevron on the right. The problem I ran into there was trying to figure out the height of the individual listItem renderer after it is rendered (and word wrapped).
The problem comes from having flexDirection: 'row' in the View containing your text. This makes the text overflow to the right instead of wrapping. If you want your text to wrap, the containing View must have flexDirection: 'column' in the style.
I've modified your code accordingly:
import React, { Component } from 'react';
import {
StyleSheet,
Dimensions,
TouchableOpacity,
Text,
View
} from 'react-native';
import Moment from 'moment'
import Icon from 'react-native-vector-icons/FontAwesome';
class ProjectListItemRenderer extends Component {
componentDidMount() {
//alert(Dimensions.get('window').height)
}
render() {
return (
<View style={styles.projectRow}>
<View style={styles.projectText}>
<Text style={styles.itemName}>{this.props.name}</Text>
<Text style={styles.itemDetails>
{`${Moment(this.props.lastUpdated).fromNow()}`}
</Text>
</View>
<View style={styles.moreContainer}>
<Icon name="chevron-right" size={15} style={styles.moreIcon} />
</View>
</View>
);
}
}
const styles = StyleSheet.create({
projectText: {
flex: 1,
flexDirection: 'column'
},
projectRow: {
flexDirection: 'row',
justifyContent: 'flex-start',
padding: 15,
},
itemName: {
fontSize: 18,
color: '#4A90E2',
},
itemDetails: {
fontSize: 12,
color: '#BBBBBB',
},
moreContainer: {
justifyContent: 'center',
alignItems: 'center'
},
moreIcon: {
color: "#d6d7da"
}
});
module.exports = ProjectListItemRenderer;
The only difference is I replaced {width: Dimensions.get('window').width - 50} with {flex: 1, flexDirection: 'column'}.