change custom radio button image onclick - react-native

I'm trying to create a button that can change the image when it is clicked, I've tried with changing its opacity now I'm trying to change the image. Here's what I've done for the custom button
const styles = StyleSheet.create({
container: {
marginVertical: normalize(5),
opacity: 0.5
},
activeButton: {
opacity: 1
}
});
export default class RadioButton extends Component {
constructor(props) {
super(props);
this.state = {
selected: this.props.currentSelection === this.props.value,
}
}
componentDidUpdate(prevProps) {
if (this.props.currentSelection !== prevProps.currentSelection) {
this.setState({ selected: this.props.currentSelection === this.props.value });
}
}
render() {
let activeButton = this.props.activeStyle ? this.props.activeStyle : styles.activeButton;
return (
<View style={[styles.container, this.props.containerStyle, this.state.selected ? activeButton : null]}>
<TouchableOpacity onPress={() => {
this.setState({ selected: !this.state.selected });
this.props.onPress();
}}>
{
this.props.element ?
this.props.element :
<Text> {this.props.value} </Text>
}
</TouchableOpacity>
</View>
);
}
}
It should be like this image

First import both images. one for selected and another for normal state.
import selectedImg from '../images/selected.png';
import normalImg from '../images/normal.png';
and then add below method to your component
btnBackgroundImage() = {
var imgSource = this.state.selected? selectedImg : normalImg;
return (
<Image
style={'put style here'}
source={ imgSource }
/>
);
}
now edit your render method like below
render() {
let activeButton = this.props.activeStyle ? this.props.activeStyle : styles.activeButton;
return (
<View style={[styles.container, this.props.containerStyle, this.state.selected ? activeButton : null]}>
<TouchableOpacity onPress={() => {
this.setState({ selected: !this.state.selected });
this.props.onPress();
}}>
{
this.btnBackgroundImage()
}
</TouchableOpacity>
</View>
);
}

Related

Styling camera on React native

On a screen, I want to scan tickets this way :
class Tickets extends Component {
constructor(props) {
super(props);
this.state = {
Press: false,
hasCameraPermission: null,
reference: '',
lastScannedUrl:null,
displayArray: []
};
}
initListData = async () => {
let list = await getProductByRef(1);
if (list) {
this.setState({
displayArray: list,
reference: list.reference
});
}
console.log('reference dans initListData =', list.reference)
};
async UNSAFE_componentWillMount() {
this.initListData();
console.log('reference dans le state =', this.state.reference)
};
componentDidMount() {
this.getPermissionsAsync();
}
getPermissionsAsync = async () => {
const { status } = await Permissions.askAsync(Permissions.CAMERA);
this.setState({ hasCameraPermission: status === "granted" });
};
_onPress_Scan = () => {
this.setState({
Press: true
});
}
handleBarCodeScanned = ({ type, data }) => {
this.setState({ Press: false, scanned: true, reference: data });
this.props.navigation.navigate('ProductDetails', {reference : parseInt(this.state.state.reference)})
};
renderBarcodeReader = () => {
const { hasCameraPermission, scanned } = this.state;
if (hasCameraPermission === null) {
return <Text>{i18n.t("scan.request")}</Text>;
}
if (hasCameraPermission === false) {
return <Text>{i18n.t("scan.noaccess")}</Text>;
}
return (
<View
style={{
flex: 1,
...StyleSheet.absoluteFillObject
}}
>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : this.handleBarCodeScanned}
style={{ flex:1, ...StyleSheet.absoluteFillObject}}
/>
{scanned && (
<Button
title={"Tap to Scan Again"}
onPress={() => this.setState({ scanned: false })}
/>
)}
</View>
);
}
render() {
const { hasCameraPermission, scanned, Press } = this.state;
let marker = null;
console.log('displayArray', this.state.displayArray, 'reference', this.state.displayArray.reference)
return (
<View style={{flex:1}}>
<KeyboardAvoidingView behavior="padding" enabled style={{flex:1}}>
<ScrollView contentContainerStyle={{flexGrow: 1 }} >
{Press ? (
<View style={{flex:1}}>
{this.renderBarcodeReader()}
</View>
) : (
<View style={{flex:1, justifyContent:'center', alignItems:'center'}}>
<Button
color="#F78400"
title={i18n.t("scan.scan")}
onPress={this._onPress_Scan}>
</Button>
</View>
)}
</ScrollView>
</KeyboardAvoidingView>
</View>
);
}
}
export default Tickets;
This code gives me
As you can see I have a top and bottom margin. I would like there to be no space, for the camera to take the entire screen (and for any buttons to be displayed over the camera image)
How can I do it, the style of which element should I change?
Thanks for any help and explanations
can you leave your code for that part? now everything is okay but i believe the image width and height is static and you are not using resizeMode for that image, for camera it will be different .
you can check resizeMode for the camera library you are using

How to null check and navigate to new screen on click submit when textinput and submit button both are in different js files in react native?

render(){
return (
<ImageBackground
source={require('../images/back02.png')}
style={styles.bgscreen}
>
<KeyboardAvoidingView behavior='position'>
<Image
style={styles.headImage}
source={require('../images/login_img.png')}
/>
<ImgBack/>
</KeyboardAvoidingView>
<BottomButton navigation={this.props.navigation} />
</ImageBackground>
);}
}
ImgBack contains username and password textinput.
BottomButton contains the submit button
I want to navigate to new activity when submit button clicked. navigation to new screen is working perfectly but before navigating i want to null check the TextInput which are on
I am new to React-Native. Complete Beginner here. I want even know what to do. Help.
ImgBack.js file
class imgBack extends React.Component {
constructor()
{
super();
this.state = { hidePassword: true }
}
managePasswordVisibility = () =>
{
this.setState({ hidePassword: !this.state.hidePassword });
}
usernameValidate = (EnteredValue) =>{
var TextLength = EnteredValue.length.toString();
if(TextLength == 10 ){
Alert.alert("Sorry, You have reached the maximum input limit.")
}
else if(TextLength == 0){
Alert.alert("Username can't be blank")
}
}
passValidate = (EnteredValue) =>{
var TextLength = EnteredValue.length.toString();
if(TextLength == 10 ){
Alert.alert("Sorry, You have reached the maximum input limit.")
}
else if(TextLength == 0){
Alert.alert("Username can't be blank")
}
}
render(){
return (
<ImageBackground resizeMode='contain'
source={require('../images/login_back.png')}
style={{
marginHorizontal: 10,
height: 290,
padding: 30,
}}>
<View style={
styles.textInputContainer
} >
<TextInput
placeholder="Username"
underlineColorAndroid = "transparent"
placeholderTextColor="#000000"
maxLength={10}
onChangeText={ EnteredValue => this.usernameValidate(EnteredValue) }
/>
</View>
<View style = { styles.textInputContainer }>
<TextInput
onChangeText={ EnteredValue => this.passValidate(EnteredValue) }
underlineColorAndroid = "transparent"
secureTextEntry = { this.state.hidePassword }
placeholder="Password"
placeholderTextColor="#000"
/>
<TouchableOpacity style = { styles.visibilityBtn } onPress = { this.managePasswordVisibility }>
<Image source = { ( this.state.hidePassword ) ? require('../images/eye_close_icon.imageset/eye_close_icon.png') : require('../images/eye_icon.imageset/eye_icon.png') } style = { styles.btnImage } />
</TouchableOpacity>
</View>
</ImageBackground>
)
}
} ```
**Bottombutton File**
class bottomButon extends Component {
render(){
return (
<ImageBackground
style={{ height: 80, marginLeft: '20%', marginTop: 10 }}
resizeMode={'center'}
source={require('../images/btn_back.png')} >
<TouchableOpacity
onPress={ this.login } >
<Text style={{ textAlign: 'center', marginTop: 25 }}>Submit & SYNC</Text>
</TouchableOpacity>
</ImageBackground>
)
} }
export default bottomButon; ```
solution:
constructor(props) {
super(props);
this.state = {
hidePassword: true,
username: '',
password: '',
};
}
validUserPass = async () => {
try {
if (this.state.username === '') {
Alert.alert('Username is required !');
} else if (this.state.password === '') {
Alert.alert('Password is required !');
} else {
this.props.navigation.navigate('selectEmoji');
}
} catch (error) {
console.warn(error);
}
};
it helped me solve my issue.

React Native Pass Index to Props

I have a modal that contain icons and description and status, and i want to pass the icons and descriptions from index to the modal,I already pass the status. is there anyway to do that? sorry i'm still new to react native and thanks in advance
this is my index.js
export const img =
{
itemStatus: {
"Open": { name: 'open-book', type: 'entypo', color: '#ffb732', desc:'New Attribut, New Attention'},
"Approved": { name: 'checklist', type: 'octicon', color: '#3CB371', desc:'Approved by SPV/MNG' },
"Escalated": { name: 'mail-forward', type: 'font-awesome', color: '#ffb732', desc:'Escalated to SPV/MNG' },
"Deliver Partial": { name: 'arrange-send-to-back', type: 'material-community', color: '#8B4513', desc:'Some items in a DO have not arrived/was faulty' },
};
and this is my container
class MyRequest extends React.Component {
constructor() {
super();
this.state = {
currentStatus: null,
refreshing: false,
fetchStatus: null
};
handleShowModal = (status) =>{
this.setState({
currentStatus: status,
});
}
handleDismissModal = () =>{
this.setState({currentStatus: null});
}
<View style={[styles.panelContainer, status === 'success' ? {} : { backgroundColor: color.white }]}>
<FlatList
showsVerticalScrollIndicator={false}
progressViewOffset={-10}
refreshing={this.state.refreshing}
onRefresh={this.onRefresh.bind(this)}
onMomentumScrollEnd={(event) => event.nativeEvent.contentOffset.y === 0 ? this.onRefresh() : null}
data={content}
renderItem={({ item }) => item}
keyExtractor={(item, key) => key.toString()}
/>
</View>
<IconModal visible={this.state.modalVisible} close={this.handleDismissModal} icon={} status={this.state.currentStatus} desc={} />
}
and this is my modal
const IconModal = (props) => {
return(
<Modal
isVisible={props.visible}
onBackdropPress={props.close}
>
<View style={styles.dialogBox}>
<View style={styles.icon}>
<Icon>{props.icon}</Icon>
</View>
<View style={styles.text}>
<Text style={styles.status}>{props.status}</Text>
<Text>{props.desc}</Text>
</View>
<TouchableOpacity onPress={props.close}>
<View>
<Text style={styles.buttonText}>GOT IT</Text>
</View>
</TouchableOpacity>
</View>
</Modal>
)
}
It's a bit unclear how you plan on mapping against img.itemStatus index but you can just reference the object you want as such.
import img from '....path_to_index.js'
...
// const currentItemStatus = img.itemStatus.Open
// OR
const itemStatus = 'Open' // Or 'Approved', 'Escalated', 'Deliver Partial'
const currentItemStatus = img.itemStatus[itemStatus]
...
<IconModal
visible={this.state.modalVisible}
close={this.handleDismissModal}
icon={currentItemStatus.name} // Passing name
status={this.state.currentStatus}
desc={currentItemStatus.desc} // Passing desc
/>
...
Hope this was helpful

React Native onPress active state change image source on Carousel

Trying to change image of a button on my carousel elements, currently it (below code) changes all the images when I click any of them. I'd like change that only current carousel's image. Any ideas? Thanks
class CarouselImages extends React.Component {
constructor(props) {
super(props);
this.state = {
myImagesArray: [
{
key: 1,
title: 'Category'
},
{
key: 2,
title: 'Category'
},
{
key: 3,
title: 'Category'
}
],
icon_active: false,
}
activateCarouselButton = a => {
const newState = Object.assign(
{},
{
icon_active: false,
},
{ [a]: true },
)
this.setState(newState);
}
}
render = () => {
const { icon_active } = this.state;
var myCarousel = this.state.myImagesArray.map(function (index) {
return (
<View key={index}>
<TouchableHighlight onPress={() => activateCarouselButton('icon_active')} >
<Image
source={icon_active ? require('../Image/active#2x.png') : require('../Image/disabled#2x.png')} />
</TouchableHighlight>
</View>
);
});
return (
<View>
<Carousel
style={{ backgroundColor: '#fff' }}>
{myCarousel}
</Carousel>
</View>
)
}
}
You need to hold key of the icon in the icon_active state, not a boolean. This gives you a hunch on how to do it:
render() {
const { icon_active } = this.state;
return (
this.state.myImagesArray.map((image) => {
return (
<View key={image.key}>
<TouchableHighlight onPress={() => activateCarouselButton(image.key)}>
<Image source={icon_active === image.key ? require('../Image/active#2x.png') : require('../Image/disabled#2x.png')} />
</TouchableHighlight>
</View>
)
})
)
}
<Image source={this.props.secureTextEntry ?
require('../../assets/images/signup/Showpassword.png') :
require('../../assets/images/signup/Hidepassword.png')} />

React Native - How to re-render Navigator component on icon press

How would I re-render/ change the colour of a Navigator component icon when it is pressed. I have TouchableHighlight on it but I need the state to stay permanently. For example someone presses a 'favourite' heart icon, and it turns from grey to red. I've been trying to figure out a solution for some time now.
This is the section of my code where the change should happen. I need my if statement and Navigator icon to re-render based on the true/false value which changes when the TouchableHighlight onPress triggers.
var NavigationBarRouteMapper = {
RightButton: function(route, navigator, index, navState) {
// * The button displayed in the top right of the navigator
switch(route.id) {
case('businessProfile'):
if (route.isFavourited) {
return (
<View style={[ styles.multipleIcons ]}>
<TouchableOpacity
onPress={() => {
var favouriteBusiness = new FavouriteBusiness();
favouriteBusiness.updateBusinessAsFavourite(route.business.id)
}}
style={[ styles.navBarButton, styles.iconRightPaddingLarge ]}
>
<IconFA
name='heart'
size={ 25 }
color='#de6262'
style={ styles.icon }
/>
</TouchableOpacity>
</View>
);
} else {
return (
<View style={[ styles.multipleIcons ]}>
<TouchableOpacity
onPress={() => {
var favouriteBusiness = new FavouriteBusiness();
favouriteBusiness.updateBusinessAsFavourite(route.business.id)
}}
style={[ styles.navBarButton, styles.iconRightPaddingLarge ]}
>
<IconFA
name='heart'
size={ 25 }
color='#ddd'
style={ styles.icon }
/>
</TouchableOpacity>
</View>
);
}
default:
return null;
}
},
};
<Navigator
ref='navigator'
sceneStyle={ [styles.container, styles.inner] }
initialRoute={{
id: this.props.scene,
title:this.props.title
}}
renderScene={ this.renderScene }
configureScene={(route) => {
if (route.sceneConfig) {
return route.sceneConfig;
}
return Navigator.SceneConfigs.FloatFromRight;
}}
navigationBar={
<Navigator.NavigationBar
routeMapper={ NavigationBarRouteMapper }
style={ styles.navigationBar }
/>
}
/>
if you still did not get the solution perhaps these could help.
you can define some Properties in construktor:
constructor(props) {
super(props);
this.state = {
color: 'lightgrey',
};
}
You can define the Icon in the RooteMapper of the Navigaton bar:
return (<Icon
name="star"
style={[styles.rightHadderButton, {color: this.state.color}]}
onPress={RightNavigatorButton.favoriteStar.bind(this)}/>);
and then change the collor in the onpress defined Function:
exports.favoriteStar = function(event) {
if (this.state.color === 'lightgrey') {
this.setState({ color: '#990000' });
AlertIOS.alert( "favoriteStar","Favorite");
} else {
this.setState({ color: 'lightgrey' });
AlertIOS.alert( "favoriteStar","notFavorite");
}
}
Hope these works for you too and it helps you.