Change state of clicked button inside StreamBuilder list in Flutter - flutter

I have a StreamBuilder which returns me a ListView of items.
For each item I also have ElevatedButton button.
ElevatedButton(
onPressed: () {
setState(() {
pressGeoON = !pressGeoON;
if (pressGeoON == true) {
favoriteDataList.add(snapshot
.data?.docs[index].id);
} else {
favoriteDataList.removeWhere(
(item) =>
item ==
snapshot.data
?.docs[index].id);
}
});
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<
Color>(
Colors.deepPurple,
),
),
child: Icon(
Icons.favorite,
color: pressGeoON
? Colors.blue
: Colors.red,
),
)
I'm trying to change state of only clicked button, but so far with my code it always changes state of all buttons inside of list.
How can I change state only of clicked button and not all of them?

Related

How to make a button to have some active or inactive effect when a menu is being displayed and hidden in flutter (using "showMenu" )

I am using showMenu() function to create and render a menu when onTap() on a certain ListTile widget. So, How to make the ListTile show in an active/inactive state (using some background colour) when the menu is active and vice versa.
PS. I am able to achieve active state when the list tile is clicked using onTap() but unable to achieve the inactive state as I am unable to find a way of reverting the `List Tile background colour because there is no toggle/function when the pop-up menu from show menu is closed.
Please check the below images to get more clarity on the issue.
inactive state
active and menu open
menu closed but colour is still in effect
// List to maintain active states (item will be pushed to list on onTap() function)
List sideOptions = [];
// function to return color w.r.t if statements
Color changeBackground(bool isHovered, String sideOption) {
print(currentRoute);
if ((isHovered || (currentRoute == "/$sideOption")) ||
sideOptions.contains(sideOption)) {
return global_styles.blueShade;
} else {
return Colors.transparent;
}
}
// ListTile wrapped in a container
// OnHoverIcon() is a function i wrote to capture hover events if any
// ListTile onTap() function
_buildPopUpMenuButton(
String title, String iconString, List<PopupMenuEntry> subItems) {
child: OnHoverIcon(builder: (isHovered) {
return Container(
height: 55,
decoration: BoxDecoration(
color: changeBackground(isHovered, title),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(8.0),
topRight: Radius.circular(8.0),
),
),
child: ListTile(
onTap: () => {
sideOptions.add(title),
if (!_isDropdownOpen)
{_controller.forward(), _isDropdownOpen = true}
else
{
_controller.reverse(),
_isDropdownOpen = false,
},
// _isDropdownOpen = true,
showMenu(
context: context,
position: getSizeandPosition(),
items: subItems)
},
leading: Image.asset(
iconString,
color: changeIconColors(isHovered, title),
),
title: Text(
title,
style: sideNavItems(isHovered, title),
),
trailing: title != "Settings"
? RotationTransition(
turns: _rotationAnimation,
child: Icon(
Icons.keyboard_arrow_up,
color: changeIconColors(isHovered, title),
),
)
: null,
),
);
}
);
}
}`
showMenu() returns a Future that ends when the menu is popped. So, you can place an await before it and it'll continue to the next line when the menu is popped.
Like this:
void onTap() async {
// Set the tile as active (changes the color to blue)
setState(() {
isActive = true;
});
// Show menu and wait for it to pop.
await showMenu(
/* ... */
);
// Menu is popped. Set the tile as inactive and return to the default color.
setState(() {
isActive = false;
});
}
Edit: It's best to extract the button to its own StatefulWidget so setState() will update just the button instead of the whole page.
If this doesn't work with your code. Maybe place a stateful widget in the menu and use dispose() to detect when it's no longer active and trigger the inactivation method.

flutter checkbox checked on container clicked

When I click on the checkbox it checked. What I want is even if I click on the entire container wrapping the checkbox, it checked also. But I can't seem to find a way.
Here is my code:
InkWell(
onTap: () {},
child: Container(
child: Checkbox(
activeColor: Color(0xFF2481CF),
shape: CircleBorder(
side: BorderSide(
color: Colors.grey
)
),
checkColor: Colors.white,
value: contactList[index].select,
onChanged: (value) {
var query = mains.objectbox.boxContact.query(ContactModel_.email.equals(contactList[index].email.toString())).build();
setState(() {
...
})
...
Is there any solution?
You can update the Checkbox value when it was tapped - which I see you already have an InkWell wrapping the Checkbox.
Assuming that contactList[index].select contains a bool, you can do something similar to this.
Inkwell(
onTap: () {
setState((){
contactList[index].select = !contactList[index].select;
});
},
...
)

How to make a container as a radio button in Flutter and make sure it doesn't deselect

I have used a package group_button 4.2.1 but once i select the textfields the radio buttons deselect and i have to select again, i have tried using the controller property of the Widget but i didn't get it to work.
I was thinking if i can make a container from scratch that is a radio button and can retain the value once i finish filling the form to be submitted to my firestore database.
You can use List of button text and keep tract of selectedIndex.
Run on dartPad
int? _selectedValueIndex;
List<String> buttonText = ["ForSale", "For rent"];
Widget button({required String text, required int index}) {
return InkWell(
splashColor: Colors.cyanAccent,
onTap: () {
setState(() {
_selectedValueIndex = index;
});
},
child: Container(
padding: const EdgeInsets.all(12),
color: index == _selectedValueIndex ? Colors.blue : Colors.white,
child: Text(
text,
style: TextStyle(
color: index == _selectedValueIndex ? Colors.white : Colors.black,
),
),
),
);
}
Inside build method to use this,
Row(
children: [
...List.generate(
buttonText.length,
(index) => button(
index: index,
text: buttonText[index],
),
)
],
),

Flutter Button statemanagement using provider

In my flutter application I have a button for follow and unfollow a user.
buttonstate.isSelected && widget.user!.isFollowing == true
? ElevatedButton(
onPressed: () async {
await unfollowuser(widget.user!.id); //Api Call
},
child: Text(
'Following',
style: TextStyle(
color: Theme.of(context).disabledColor,
),
),
)
: ElevevatedButton(
onPressed: () async {
buttonstate.setButtonState(true);
await followuser(widget.user!.id); //Api Call
},
child: Text(
'Follow',
style: TextStyle(
color: Theme.of(context).accentColor,
),
),
),
My objective is whenever the button is pressed I want the Api call to happen as well as the state of the button should change from 'Follow' to 'Following'. Now the Api gets called, but the button wont change to 'following'. After the page is refreshed, button changes to 'following'. How can i manage state of the button using provider??
Ive created a provider for this purpose as follows
import 'package:flutter/material.dart';
class ButtonProvider with ChangeNotifier {
bool isSelected = false;
void setButtonState(bool value) {
isSelected = value;
notifyListeners();
}
bool? get buttondata {
return isSelected;
}
}

How to show icon on specific area after click on button?

My Goal:
When user click on RaisedButton i would like to show a icon.
My problem:
I don't know how to show icon on specific area
My code:
This code generate some responses buttons (Europe, Asia, Africa, ..)
for (var i = 0; i < NumberChoice; i++)
RaisedButton(
color: _colorButton,
child: new Text(
_choice[i],
style: TextStyle(
fontSize: 20.0, color: Colors.white),
),
onPressed: () {
setState(() {
if (_choice[i] == answer) {
print("--------------- Corect ----------------");
//--HERE HOW TO SHOW ICON IF USER CLICK ON BUTTON--
Icon(
Icons.check,
color: Colors.green,
size: 24.0,
);
scoreResult = 1;
} else {
print("--------------- False ------------------------");
//--HERE HOW TO SHOW ICON IF USER CLICK ON BUTTON--
Icon(
Icons.close,
color: Colors.red,
size: 24.0,
);
scoreResult = 0;
}
});
},
)
Example
If user click on "Europe" , then "Icons.check" displayed where i added "Button here" .
From what i understand
create a string like this : -
String choice;
change it to true whenever u click on raised button
choice == answer
? // show widget if correct
: SizedBox()