custom radio buttons not working in react native - react-native

i am creating custom radio btns. my code is as follows:
const [isAvailable, setIsAvailable] = useState([
{id: 0, value: true, title: 'Always available', selected: true},
{id: 1, value: false, title: 'Never available', selected: false},
{
id: 2,
value: false,
title: 'Availabe for specific hours',
selected: false,
},
]);
Now, my radio component is being called by a series of assets, but the basic idea is that when i call the radio component, the respective view is shown. The radio btns are called as follows:
{isAvailable.map(option => (
<Row
key={option.id}
rightComponent={'radio'}
title={option.title}
onPress={() => onPress(option)}
isSwitched={option.selected}
/>
))}
And my OnPress function looks like this:
const onPress = option => {
setIsAvailable(
isAvailable.map(isAvailableOption => {
isAvailableOption.id === option.id
? {...isAvailableOption, selected: true}
: {...isAvailableOption, selected: false};
}),
);
};
Now, my Row component looks like this:
rightComponent === 'radio' ? (
<TouchableOpacity
style={styles.radioBtn}
onPress={onPress}
key={key}>
{isSwitched === true ? (
<>
<Ionicons
name={'radio-button-on-outline'}
style={{...styles.rightIcon, ...rightIconColor}}
/>
</>
) : (
<>
<Ionicons
name={'ellipse-outline'}
style={{...styles.rightIcon, ...rightIconColor}}
/>
</>
)}
</TouchableOpacity>
) : ({...})
But, whenever I click any icon, it doesn't work, please tell me where am I going wrong here?

Firstly you should use custom radio button because of this problems and you should use
//flexDirection:'row' in <View> <TouchableOpacity style={{//Your style}}/></View>`insted of Row. Like:`
<View style={{flexDirection:'row"}}>
<View>
{isAvailable.map(option => (
<TouchableOpacity onPress={() => onPress(option)} style={{option.isSwitched ? style:style}} >
<Text>optin.title </Text>
</TouchableOpacity>
))}
</View>

Nothing was wrong, I just had to put my TouchableOpacity inside a View

can u try this :
{isSwitched === true ? (
<TouchableOpacity
style={styles.radioBtn}
onPress={onPress}
key={key}>
<Ionicons
name={'radio-button-on-outline'}
style={{...styles.rightIcon, ...rightIconColor}}
/>
</TouchableOpacity>
) : (
<TouchableOpacity
style={styles.radioBtn}
onPress={onPress}
key={key}>
<Ionicons
name={'ellipse-outline'}
style={{...styles.rightIcon, ...rightIconColor}}
/>
</TouchableOpacity>
)}

Related

Flatlist simulating different pages

I have to build 5 pages but as they have all the same layout I want to use a flatlist to populate the fields, my doubt us vary basic, I read the documentation and had problems to fully understand, here is my code
const DATA = [
{
picture: '../../Components/Images/wellbeing.png',
text1: 'Get weekly overviews and find',
text2: 'out whats impacting your health',
text3: 'and wellness',
percent: 20,
},
];
const Item = ({picture, text1, text2, text3, percent}) => (
<View style={styles.container}>
<View>
<Image source={require({picture})} style={styles.image} />
</View>
<View style={styles.text_field}>
<Text style={styles.textContent}> {text1} </Text>
<Text style={styles.textContent}> {text2} </Text>
<Text style={styles.textContent}> {text3} </Text>
</View>
<View style={styles.footer}>
<TouchableOpacity onPress={() => navigation.navigate('HabitTracking')}>
<ProgressCircle
percent={{percent}}
radius={30}
borderWidth={3}
color="#3399FF"
shadowColor="white"
bgColor="blue">
<Icon name="arrowright" size={25} color="white"></Icon>
</ProgressCircle>
</TouchableOpacity>
</View>
</View>
);
I'm having trouble on how to populate this in the class, here is what I have so far
const Wellcome = () => {
const renderItem = ({picture, text1, text2, text3, percent}) => (
<Item picture={Item.picture}
/>
);
return (
);
};
export default Wellcome;
am I doing everything wrong?
please let me know if you need any further information
const renderItem = (item) => (
<Item picture={item.picture} />
);
and call renderItem in your render method
...
{renderItem(item)}
...
where item looks something like...
{
picture: 'something',
text1: 'something',
text2: 'something',
text3: 'something',
percent: 'something'
}

React native, using TouchableOpacity onPress

I just started learning react native. I am currently trying to implement TouchableOpacity on image rendering from an array and use the info for that element from the array to create a new page. The goal of the code is to have a userInfo page that lists all the images and once you tap on an image, it will show details of that user (you will see just this user and no other ones) using userDetails. I know my TouchableOpacity part will not work, but I don't know how to make it work.
This is from my userInfo.js:
const UserInfo =() => {
const users = [
{userName: "A",
imageSource: require("../../assets/users/A.jpg"),
bio: "this is A"
},
{userName: "B",
imageSource: require("../../assets/users/B.jpg"),
bio: "this is B"
},
{userName: "C",
imageSource: require("../../assets/users/C.jpg"),
bio: "this is C"
}
]
return(
<FlatList
showsVerticalScrollIndicator={false}
keyExtractor={(users)=> users.userName}
data={users}
renderItem = {({item})=>{
return <View>
<TouchableOpacity onPress={userInfoLink(users.userName, users.imageSource, users.bio)}>
<View style={styles.viewBox}><Image style={styles.image} source={item.imageSource}/></View>
</TouchableOpacity>
<Text style={styles.text}>{item.userName}</Text>
</View>;
}}
/>
)
};
This is from my userDetails.js:
const UserDetail=({imageSource, userName, bio}) => {
return <View>
<View style={styles.viewBox}><Image style={styles.image} source={imageSource}/></View>
<Text style={styles.text}>User name: {userName}</Text>
<Text style={styles.text}>Bio: {bio}</Text>
</View>;
}
Ok, after doing some research I found a way to make it work. I used navigation.navigate and passing parameters into the page.
Here is my return code in UserInfo.js:
return(
<FlatList
showsVerticalScrollIndicator={false}
keyExtractor={(users)=> users.userName}
data={users}
renderItem = {({item})=>{
return <View>
<TouchableOpacity onPress={()=>{navigation.navigate('UserDetails', {imageSource: item.imageSource, userName: item.userName, bio:item.bio })}}>
<View style={styles.viewBox}><Image style={styles.image} source={item.imageSource}/></View>
</TouchableOpacity>
<Text style={styles.text}>{item.userName}</Text>
</View>;
}}
/>
)
Here is the code in UserDetails.js:
const UserDetail=({navigation}) => {
const imageSource = navigation.getParam('imageSource', 'a no image image');
const userName = navigation.getParam('userName', 'username error');
const bio = navigation.getParam('bio', 'bio error');
return <View>
<Text style={styles.title}>User Detail</Text>
<View style={styles.viewBox}><Image style={styles.image} source={imageSource}/></View>
<Text style={styles.text}>User name: {userName}</Text>
<Text style={styles.text}>Bio: {bio}</Text>
<Button title="User Info" onPress={()=>{navigation.navigate('UserInfo')}}/>
</View>;
}
I am wondering if adding the parenthesis and arrow was what fixed it.
You went from:
onPress={userInfoLink(users.userName, users.imageSource, users.bio)}
To this:
onPress={()=>{navigation.navigate('UserDetails', {imageSource: item.imageSource, userName: item.userName, bio:item.bio })}}

Why section List in react native is not return correct row data?

This is my data to render in Section List
this.state = {
data: [
{
title: "Popular Items",
data: [
{
key: 1,
name: "Briyani",
image: "https://bootdey.com/img/Content/avatar/avatar6.png",
uniqueID: 1,
cnt: 0
},
{
key: 2,
name: "Chicken Lollypop",
image: "https://bootdey.com/img/Content/avatar/avatar1.png",
uniqueID: 2,
cnt: 0
},
{
key: 3,
name: "Chicken kabab",
image: "https://bootdey.com/img/Content/avatar/avatar7.png",
uniqueID: 3,
cnt: 0
}]}]};
SectionList to Display
<SectionList
sections={this.state.data}
renderSectionHeader={({ section }) => {
return (
<View style={styles.titleContainer}>
<Text style={styles.title}>{section.title}</Text>
</View>
);
}}
keyExtractor={item => item.uniqueID.toString()}
extraData={this.state}
renderItem={({ item }) => {
return (
<View style={styles.container}>
{item.cnt === 0 ? (
<Button
title="Add"
onPress={e =>
this.incrementItem(e, item.uniqueID, item.cnt)
}
/>
) : (
<View>
<Button
title="-"
onPress={e =>
this.decrementItem(e, item.uniqueID, item.cnt)
}
/>
<Text>
{item.cnt}
</Text>
<Button
title="+"
onPress={() =>
this.incrementItem(item.uniqueID, item.cnt)
}
/>
</View>
)}
</View>
);
}}
/>
Initially the cnt = 0 based on that condition i render first button After i press i increment the count correctly based on uniqueID and re-render the component .Again when i Press on newly rendered Button it returns different uniqueID. Is there any solution to solve this. Thanks in advance.
I figured it out its because of i didn't pass event argument in incrementItem function i only pass two arguments but i didn't know why the function called if we even pass two arguments but function expects three params.

React Native - Change other icons color on click

I've been searching for a few days to solve this problem. I need to change another icon's color when i click in one of them.
I'm using react-native-vector-icons
this.setState({
listaPlantel: Object.entries(dataArray).map(function ([key, nome]) {
if (that.state.mercado.status_mercado == 2) {
dadosAtleta = that.state.pontuados[nome.atleta_id];
}
return (
<ListItem avatar key={key} button onPress={() => that.detailsScreen(nome)}>
<Left>
<Thumbnail source={{ uri: nome.foto.replace('FORMATO', '80x80') }} />
</Left>
<Body>
<Text>{nome.apelido}</Text>
<Text note>{that.state.posicoes ? that.state.posicoes[nome.posicao_id]['nome'] : ''} - {that.state.clubes ? that.state.clubes[nome.clube_id]['nome'] : ''}</Text>
<Text style={{ textAlign: 'left' }}>Última: {nome.pontos_num} Média: {nome.media_num} {' $' + nome.preco_num}</Text>
</Body>
<Right>
{/*<Text>{dadosAtleta ? dadosAtleta['pontuacao'] : nome.pontos_num}</Text>*/}
<Icon name="md-close-circle" size={30} />
<Icon type="Foundation" name="md-contact" key={key} size={30} color={that.state.id_capitao === nome.atleta_id ? that.state.corCap : that.state.corGeral} onPress={() => that.setState({ id_capitao: nome.atleta_id })} />
</Right>
</ListItem>
)
}),
});
It seems you are putting conditions and functions within setState I would recommend you read about the lifecycle and app state here:
https://reactjs.org/docs/state-and-lifecycle.html
As an example of how to update values, of which you're trying to do - take this scenario into consideration:
initial colour : red, updated colour : blue (For example)
in your constructor:
constructor (props) {
super(props);
this.state = {
/*Initial State and Colour*/
iconColour : "red"
}
}
in your render method:
<ListItem avatar key={key} button onPress={() => that.detailsScreen(nome)}>
<Icon color={this.state.iconColour}/>
</ListItem>
Within your onPress function:
this.setState({
iconColor : "blue"
})

how to change only clicked button color from collection of buttons in react-native

how to change only clicked button color from the collection of buttons in react-native by onPress.
Button Text Should also change by onPress.
Sample Code
export class App extends Component {
changeColor() {
// code here
}
render() {
return (
<View style={styles.button_view}>
<TouchableOpacity onPress={this.changeColor.bind(this)} style={styles.button}>
<Text style={styles.button_text}>
Button 1
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.changeColor.bind(this)} style={styles.button}>
<Text style={styles.button_text}>
Button 2
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.changeColor.bind(this)} style={styles.button}>
<Text style={styles.button_text}>
Button 3
</Text>
</TouchableOpacity>
</View>
)
}
}
I tried this and it worked ,btw it`s a little long way;
First set a flag for each of them like:
constructor(props){
super(props);
this.state={
button_1 : false,
button_2 : false,
button_3 : false,
button_4 : false,
}
then,for each Button do this:
<Button
title="Button 1"
color={this.state.button_1 ? "green" : "gray"}
onPress={() => {
this.setState({
button_1: !this.state.button_1,
button_2: false,
button_3: false,
button_4: false
});
}}
/>
<Button
title="Button 2"
color={this.state.button_2 ? "green" : "gray"}
onPress={() => {
this.setState({
button_1: false,
button_2: !this.state.button_2,
button_3: false,
button_4: false
});
}}
/>
do this for text too,it will work
From your code, it looks like all the buttons have the same styling, so I would create a custom button component and render it and pass a flag such as active and set it to true from parent component within the changeColor() method.
You can then have styling based on the active prop.
i.e: style={{ color: this.props.active? 'red' : 'white';}}