How to make Toggle Selected Image in Flutter? - flutter

I've tried several tutorials to create layouts like this, but they always fail.
maybe someone can help here

Can you please elaborate a bit more? As far as I know there is no direct way to make this. What you would need is to have a variable selectedImageIndex and you would have 2 "images" for each image, one that is highlighted and one that isn't and then you would write something like
child: selectedImageIndex == 1? HighlightedImage():NonHighLightedImage
and each image would be wrapped with a Gesture Detector so that when you tap it the selectedImageIndex changes. But again, that would mean that you have both versions of the image (or you have to manually somehow highlight it, or if it's an icon perhaps change color of icon. Please do provide more details
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int selected;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
IconButton(
icon: Icon(Icons.school),
color: (selected != null && selected == 0)
? Colors.blue
: Colors.grey,
onPressed: () {
setState(() {
selected = 0;
});
},
),
IconButton(
icon: Icon(Icons.school),
color: (selected != null && selected == 1)
? Colors.blue
: Colors.grey,
onPressed: () {
setState(() {
selected = 1;
});
},
)
],
),
),
);
}
}

Do let me know if it didn't work.
int _selectedA = 1, _selectedB = 1;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_buildCircleA(icon: Icons.bluetooth, selection: 1),
_buildCircleA(icon: Icons.bluetooth_disabled, selection: 2),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_buildCircleB(icon: Icons.mail, selection: 1),
_buildCircleB(icon: Icons.mail_outline, selection: 2),
],
)
],
),
),
);
}
Widget _buildCircleA({IconData icon, int selection}) {
return GestureDetector(
onTap: () => setState(() => _selectedA = selection),
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: _selectedA == selection ? Colors.blue : Colors.transparent, width: 2),
),
child: Icon(icon, size: 56, color: _selectedA == selection ? Colors.blue : null),
),
);
}
Widget _buildCircleB({IconData icon, int selection}) {
return GestureDetector(
onTap: () => setState(() => _selectedB = selection),
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: _selectedB == selection ? Colors.blue : Colors.transparent, width: 2),
),
child: Icon(icon, size: 56, color: _selectedB == selection ? Colors.blue : null),
),
);
}

Related

error [Get] the improper use of a GetX has been detected. using bottomNavigationBar

I'm trying to implement a bottomNavigationBar, but I can't finish it, I'm using Get to handle the routes and the state of the application.
I'm new to flutter, but reading the documentation I still don't understand
This is the main widget.
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
backgroundColor: AppColors.black,
title: Center(
child: CommonAssetImage(
asset: 'logo.png',
color: AppColors.white,
height: 30,
),
),
),
body: BodyTabsScreen(),
bottomNavigationBar: HomeScreenBottomNavigatorBar()),
);
}
then,I have this widget where call other widget.In this widget I using Obs.
class HomeScreenBottomNavigatorBar extends StatelessWidget {
const HomeScreenBottomNavigatorBar({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Material(
elevation: 10,
color: AppColors.white,
child: Container(
height: 60,
padding: const EdgeInsets.symmetric(horizontal: 27),
color: AppColors.white,
child: Obx(() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TabsScreenBottomNavigationTab(
isActive: true,
label: 'Buy',
icon: Icons.home,
onTap: () {}),
TabsScreenBottomNavigationTab(
label: 'My account',
// icon: IkramIcons.user,
// iconSize: 20,
icon: (Icons.home),
onTap: () {}),
],
);
}),
),
);
}
}
class TabsScreenBottomNavigationTab extends StatelessWidget {
final String label;
final IconData icon;
final Widget image;
final VoidCallback onTap;
final bool isActive;
final double iconSize;
const TabsScreenBottomNavigationTab({
Key key,
this.label,
this.icon,
this.image,
this.onTap,
this.isActive,
this.iconSize = 20,
}) : super(key: key);
#override
Widget build(BuildContext context) {
final _inactiveTextStyle = Theme.of(context).textTheme.bodyText2;
final _activeTextStyle =
_inactiveTextStyle.copyWith(color: AppColors.white);
const _commonDuration = Duration(milliseconds: 200);
final _availableSpace = MediaQuery.of(context).size.width - 27 * 2;
final _inactiveWidth = _availableSpace * .2;
final _activeWidth = _availableSpace * .35;
return AnimatedContainer(
duration: _commonDuration,
width: isActive ? _activeWidth : _inactiveWidth,
height: 35,
child: Material(
color: Colors.transparent,
shape: const StadiumBorder(),
clipBehavior: Clip.antiAlias,
child: AnimatedContainer(
duration: _commonDuration,
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
child: AnimatedDefaultTextStyle(
style: isActive ? _activeTextStyle : _inactiveTextStyle,
duration: _commonDuration,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (icon != null)
Icon(
icon,
size: iconSize,
color: isActive ? AppColors.white : AppColors.black,
),
if (image != null) image,
if (isActive)
Container(
margin: const EdgeInsets.only(left: 8),
child: Text(label),
)
],
),
),
),
),
),
),
);
}
}
Getx will always throw that error when you use Obx or Getx widget without inserting an observable variable that widget. So if you are NOT trying to rebuild a widget based on an updated value of a variable that lives inside a class that exends GetxController, then don't use a Getx widget.
If you're just trying to use Getx for routing, then make sure to change your MaterialApp to GetMaterialApp and define your routes, like so.
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
home: Page1(),
getPages: [
GetPage(name: Page1.id, page: () => Page1()), // add: static const id = 'your_page_name'; on each page to avoid using raw strings for routing
GetPage(name: Page2.id, page: () => Page2()),
],
);
}
}
Then in the onTap of your bottom navigation bar just use
Get.to(Page2());
Just remove the Obx widget wrapping your Row widget like this:
class HomeScreenBottomNavigatorBar extends StatelessWidget {
const HomeScreenBottomNavigatorBar({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Material(
elevation: 10,
color: AppColors.white,
child: Container(
height: 60,
padding: const EdgeInsets.symmetric(horizontal: 27),
color: AppColors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TabsScreenBottomNavigationTab(
isActive: true,
label: 'Buy',
icon: Icons.home,
onTap: () {}),
TabsScreenBottomNavigationTab(
label: 'My account',
// icon: IkramIcons.user,
// iconSize: 20,
icon: (Icons.home),
onTap: () {}),
],
);
),
);
}
}
Why? Because you are not using any observable (obs/Rx) variable in your widget tree which would trigger a rebuild when the value changes. So GetX is complaining and for good reason.
The controller should be inside Obx other wise its shows this error.
LeaderBoardController controller = Get.put(getIt<LeaderBoardController>());
Obx(()=>controller.leadBoardModel != null
? Column(
children: [
Container(
height: 180,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LeadBoardImage(type: LEADTYPE.NORMAL),
LeadBoardImage(type: LEADTYPE.CROWN),
LeadBoardImage(type: LEADTYPE.NORMAL)
]),
),
Expanded(
flex: 4,
child: ListView(
padding: EdgeInsets.symmetric(horizontal: 10.w),
children: [
for (int i = 4; i < controller.leadBoardModel!.data.result.length; i++)
LeaderBoardListItem(result:controller.leadBoardModel!.data.result[i])
],
),
)
],
)
: LoadingContainer()),
It happens when you don't use your controller value in your widget. That's why it gives error because there is no sense in using Obx or Getx() widget
MainController controller = Get.find();
return Obx(
()
{
return Column(
children: [
Text("My pretty text")
],
);
}
);
Solution :
MainController controller = Get.find();
Obx(
()
{
return Column(
children: [
Text(controller.text)
],
);
}
);
Please note that there are two required aspects: 1) extending from a GetXController, and 2) The field/method returning a value from the controller, must be computed from a Rx type. In my case, I made a sub-class of a GetXController for a test, and the return value was hard-coded (not based on a Rx value), and the ObX error occurred.
For Current Scenario You dont need to use getx for this page
(Its not proper Implementation) . please remove the OBX() your error will gone .
class HomeScreenBottomNavigatorBar extends StatelessWidget {
const HomeScreenBottomNavigatorBar({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Material(
elevation: 10,
color: AppColors.white,
child: Container(
height: 60,
padding: const EdgeInsets.symmetric(horizontal: 27),
color: AppColors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TabsScreenBottomNavigationTab(
isActive: true,
label: 'Buy',
icon: Icons.home,
onTap: () {}),
TabsScreenBottomNavigationTab(
label: 'My account',
// icon: IkramIcons.user,
// iconSize: 20,
icon: (Icons.home),
onTap: () {}),
],
);
}),
),
}

how do i change the color of a single container when they are part of an array?

I am trying to highlight the color of a GestureDetector when its tapped, I want only the tapped container color to be changed, but my GestureDetector is created from an array so when i am changing one, everything gets changed.
How do I reach to my goal ?
the texts in the arrays are not fixed and will grow or shrink.
sample gif example with current code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: MyFloat(),
);
}
}
class MyFloat extends StatefulWidget {
#override
_MyFloatState createState() => _MyFloatState();
}
class _MyFloatState extends State<MyFloat> {
List<BoxShadow> shadow = customShadow;
Color color = Colors.green;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: primaryColor,
body: SafeArea(
child: Column(
children: [
Wrap(
children: [
...(["hello", "hi", "hey"]
.map(
(val) => GestureDetector(
onTap: () {
setState(() {
this.color == Colors.green
? this.color = Colors.cyan
: this.color = Colors.green;
});
},
child: AnimatedContainer(
duration: Duration(milliseconds: 250),
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: this.color == Colors.green
? Colors.cyan
: Colors.green,
),
child: Center(
child: Text(val),
),
),
),
)
.toList())
],
)
],
),
),
);
}
}
Here is the final result :
Map<String,Color> stringColorMap = { /// Map which maps the text string to its corresponding color
"hello" : Colors.green,
"hi" : Colors.green,
"hey" : Colors.green,
};
class MyFloat extends StatefulWidget {
#override
_MyFloatState createState() => _MyFloatState();
}
class _MyFloatState extends State<MyFloat> {
Color color = Colors.green;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: Column(
children: [
Wrap(
children: [
...(["hello", "hi", "hey"]
.map(
(val){print("Val : $val"); return GestureDetector(
onTap: () {
setState(() {
/* this.color == Colors.green
? this.color = Colors.cyan
: this.color = Colors.green; */
if(stringColorMap[val] == Colors.green)
stringColorMap[val] = Colors.cyan;
else
stringColorMap[val] = Colors.green;
});
},
child: AnimatedContainer(
duration: Duration(milliseconds: 250),
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: stringColorMap[val],
),
child: Center(
child: Text(val),
),
),
);}
)
.toList())
],
)
],
),
),
);
}
}
Changes done:
What I did is I added a map which maps the text string with its corresponding color. (stringColorMap)
Then moving on the the onTap function of the widget, as you can see when the user taps the button, it will check the current color of the text and will change the color accordingly.
Then I used the color of the corresponding text as the the color of our widget.

How to change Text and Icon color depends on Background Image?

Anyone knows how to change icon and text color depending on the background color of the image or video?
The palette_generator package can help you find the most dominant color(s) in the image. You can use these color(s) to set the Text and Icon color.
Please check out the example code provided by the package author https://pub.dev/packages/palette_generator/example . The PaletteGenerator.fromImageProvider method can be used to get the color pallet from the image. You can use the following code from the example :
Future<void> _updatePaletteGenerator(Rect newRegion) async {
paletteGenerator = await PaletteGenerator.fromImageProvider(
widget.image,
size: widget.imageSize,
region: newRegion,
maximumColorCount: 20,
);
setState(() {});
}
....
Color dominantColor = paletteGenerator.dominantColor?.color;
....
Please see the entire working code below : (Add palette_generator: ^0.2.3 to your pubspec.yaml first)
import 'package:flutter/material.dart';
import 'package:palette_generator/palette_generator.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Palette Generator',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Future _updateColors;
final List<PaletteColor> _colors = [];
int _currentIndex;
final List<String> _images = [
'https://picsum.photos/id/491/200/300',
'https://picsum.photos/id/400/200/300',
'https://picsum.photos/id/281/200/300'
];
#override
void initState() {
super.initState();
_currentIndex = 0;
_updateColors = _updatePalettes();
}
Future<bool> _updatePalettes() async {
for (final String image in _images) {
final PaletteGenerator generator =
await PaletteGenerator.fromImageProvider(NetworkImage(image));
_colors.add(generator.dominantColor != null
? generator.dominantColor
: PaletteColor(Colors.blue, 2));
}
setState(() {});
return true;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Color Palette Generator Demo'),
elevation: 0,
backgroundColor: _colors.isNotEmpty
? _colors[_currentIndex].color
: Theme.of(context).primaryColor,
),
body: FutureBuilder<bool>(
future: _updateColors,
builder: (context, snapshot) {
if (snapshot.data == true)
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: double.infinity,
height: 200,
color: _colors.isNotEmpty
? _colors[_currentIndex].color
: Colors.white,
child: PageView(
onPageChanged: (value) =>
setState(() => _currentIndex = value),
children: _images
.map((image) => Container(
padding: const EdgeInsets.all(16.0),
margin: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
image: DecorationImage(
image: NetworkImage(image),
fit: BoxFit.cover,
),
),
))
.toList(),
),
),
Expanded(
child: Container(
padding: const EdgeInsets.all(32.0),
width: double.infinity,
decoration: BoxDecoration(
color: _colors.isNotEmpty
? _colors[_currentIndex].color
: Colors.white),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
"Color Palette",
style: TextStyle(
color: _colors.isNotEmpty
? _colors[_currentIndex].titleTextColor
: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 30.0,
),
),
const SizedBox(height: 10.0),
Icon(
Icons.ac_unit,
size: 100,
color: _colors.isNotEmpty
? _colors[_currentIndex].bodyTextColor
: Colors.black,
)
],
),
),
),
],
);
return const Center(child: CircularProgressIndicator());
},
),
);
}
}

Wrap middle element to new row if needed?

I have a navigation bar at the bottom of a multi-page form, with buttons to go back or forward, and an indicator for the current page.
Right now, I have the indicator place in a Row above another Row that contains the buttons, like this:
This works, and it will work even on small display sizes. However, I would rather have the indicators placed on the same row as the buttons if there is enough space, like this (except that the indicator is not centered):
The problem is, this could be too wide for some devices, especially if there are more than just a few pages. In that case, I would like either the page indicator or the buttons to "wrap" to a new row, as in the current design.
It would be easy to put everything in a Wrap, but that will make the NEXT-button wrap instead of the page indicator, since that is the last element.
Is there an easy way to make the middle element wrap onto a new row if needed? Or does one have to resort to the black magic of manually calculating sizes and creating two different layouts?
The easiest solution is to add invisible wrap to calculate the height.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: SafeArea(
child: MyHomePage(),
),
),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int currentPageIndex = 1;
int pageCount = 8;
#override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
currentPageIndex.toString(),
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
RaisedButton(
child: Text('+1 page'),
onPressed: () => setState(() => ++pageCount),
),
SizedBox(
width: 10,
),
RaisedButton(
child: Text('-1 page'),
onPressed: () => setState(() => --pageCount),
),
],
)
],
),
),
),
Container(
child: _BottomNavigation(
onPrev: () => setState(() => --currentPageIndex),
onNext: () => setState(() => ++currentPageIndex),
currentCount: currentPageIndex,
totalCount: pageCount,
),
),
],
);
}
}
class _BottomNavigation extends StatelessWidget {
const _BottomNavigation({
Key key,
#required this.totalCount,
#required this.currentCount,
#required this.onNext,
#required this.onPrev,
}) : assert(totalCount != null),
assert(currentCount != null),
assert(onNext != null),
assert(onPrev != null),
super(key: key);
final void Function() onPrev;
final void Function() onNext;
final int totalCount;
final int currentCount;
#override
Widget build(BuildContext context) {
return Stack(
children: [
buildHelper(),
buildIndicatorBar(),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_button(
'<< PREIOUS',
onPrev,
isVisible: currentCount > 1,
),
_button(
'NEXT >>',
onNext,
isVisible: currentCount < totalCount,
),
],
),
),
],
);
}
Wrap buildHelper() {
return Wrap(
children: List.generate(
totalCount,
(index) {
return Container(
width: index == 0 ? 250 : 15,
height: 20,
);
},
),
);
}
Row buildIndicatorBar() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(totalCount, (index) {
var isLast = totalCount != index + 1;
var isCurrent = currentCount == index + 1;
return Container(
height: isCurrent ? 20 : 10,
width: isCurrent ? 20 : 10,
margin: EdgeInsets.only(right: isLast ? 10 : 0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: isCurrent ? Colors.blueAccent : null,
border: Border.all(
color: Colors.blueAccent,
),
),
);
}),
);
}
Widget _button(String text, void Function() onPress, {bool isVisible}) {
return Visibility(
visible: isVisible,
child: GestureDetector(
onTap: onPress,
child: Text(text),
),
);
}
}

how would i stop the build buttons from all changing its state when clicked thanks

when clicked the buttons are meant to turn grey. this happens but the problem is that when one button is pressed all the buttons turn grey which i don't want. i only want one at a time.
var pressed = false;
Widget BuildButton(
String buttonText,
) {
MainAxisAlignment.spaceEvenly;
return new Expanded(
child: new FlatButton(
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(
15.0,
),
side: BorderSide(color: Colors.black)),
color: pressed ? Colors.grey : Colors.white, // colour change when clicked
textColor: Colors.black,
padding: EdgeInsets.all(6.0),
child: new Text(buttonText),
onPressed: () {
setState(() {
pressed = !pressed;
});
}));
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ // buttons start here
BuildButton("XXS"),
BuildButton("XS"),
BuildButton("S"),
BuildButton("M"),
]),
]),
I would suggest moving your BuildButton function into its own StatefulWidget, this way each time you create a new button, the button is in charge of managing its own state.
I've also moved the Expanded widget out of the new BuildButton widget to make it more reusable. Expanded widgets can only be used inside of Row and Column. Now your button can be used anywhere!
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
home: Home(),
),
);
}
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
BuildButton("XXS"),
BuildButton("XS"),
BuildButton("S"),
BuildButton("M"),
].map((item) => Expanded(child: item)).toList(),
),
],
);
}
}
class BuildButton extends StatefulWidget {
final String buttonText;
const BuildButton(this.buttonText);
#override
_BuildButtonState createState() => _BuildButtonState();
}
class _BuildButtonState extends State<BuildButton> {
bool pressed = false;
#override
Widget build(BuildContext context) {
return FlatButton(
onPressed: () => setState(() => pressed = !pressed),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
side: BorderSide(color: Colors.black),
),
color: pressed ? Colors.grey : Colors.white, // colour change when clicked
textColor: Colors.black,
padding: EdgeInsets.all(6.0),
child: Text(widget.buttonText),
);
}
}
Pro Tip
Use trailing commas to have the dart formatter help you keep your code readable.
The problem is that you are using pressed variable in all variable, so when you change value of pressed value, all the button change it's color.
You can create a list which contains pressed value for each button.
List<bool> pressed = [false, false, false, false];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
BuildButton("XXS", 0),
BuildButton("XS", 1),
BuildButton("S", 2),
BuildButton("M", 3),
],
),
],
),
),
);
}
Widget BuildButton(String buttonText, int index) {
return new Expanded(
child: new FlatButton(
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(
15.0,
),
side: BorderSide(color: Colors.black)),
color: pressed[index]
? Colors.grey
: Colors.white, // colour change when clicked
textColor: Colors.black,
padding: EdgeInsets.all(6.0),
child: new Text(buttonText),
onPressed: () {
setState(() {
pressed[index] = !pressed[index];
});
},
),
);
}
You need a Map of different 'pressed' states for each button.
Map<String, bool> pressed = {};
Widget BuildButton(
String buttonText,
) {
return new Expanded(
child: new FlatButton(
color: pressed['buttonText] == true ? Colors.grey : Colors.white, // colour change when clicked
textColor: Colors.black,
padding: EdgeInsets.all(6.0),
child: new Text(buttonText),
onPressed: () {
setState(() {
pressed['buttonText'] = !(pressed['buttonText'] ?? false);
});
},
),
);
}