Make selectable buttons in Flutter - flutter

I want make selectable buttons(I know how to do it but), i cant do like in example . The first button(all) doesnt need to have icon. And the last two button need to be on new line. When i try all buttons get icon, and i dont know to to make the last 2 button be on NEW LINE Can you explain to me how to do it. Thank you
List<IconData> icon = [Icons.photo, Icons.video_call, Icons.video_library, Icons.add_circle];
List<bool> isSelected = List.generate(4, (index) => false);
List<String> innerText = ['All', 'Photo', 'Video', 'Reel', 'Story']; (this in main file)
```
```
import 'package:flutter/material.dart';
import '../my_const.dart';
class MyToggleButtons extends StatelessWidget{
final List<String> text;
final List<IconData> iconData;
final List<bool> isSelected;
final Function setStateFunction;
const MyToggleButtons({Key? key, required this.text, required this.iconData, required this.isSelected, required this.setStateFunction,})
: super(key: key);
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: ToggleButtons(
isSelected: isSelected,
splashColor: Colors.green,
fillColor: Colors.transparent,
onPressed: (int index){
setStateFunction((){
isSelected[index] = !isSelected[index];
});
},
renderBorder: false,
children:
List<Widget>.generate(iconData.length, (index){
return CustomButton(
text: text[index],
iconData: iconData[index],
isSelected: isSelected[index],
);
}),
),
);
}
}
class CustomButton extends StatelessWidget {
final String text;
final IconData iconData;
final bool isSelected;
const CustomButton({Key? key, required this.text, required this.iconData, this.isSelected = false, }) : super(key: key);
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(
width: 10,
),
SizedBox.fromSize(
size: const Size(102, 52),
child: Container(
decoration: BoxDecoration(
color: isSelected ? kBlue : superWhite,
borderRadius: BorderRadius.circular(10),
border: Border.all(
width: 3.0,
color: kBlue
),
),
child: InkWell(
onTap: (){},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: const [
Icon(iconData,
color: isSelected ? Colors.white : Colors.blue,),
Text('Video', style: TextStyle(fontSize: 14, color: kBlue, fontWeight: FontWeight.w600),)
],
),
),
),
),
]
),
]
);
}
}
```
```
`

Related

How to call setsate function from a different widget?

Well, I am coding a chatbot-like page in my app. But, I am stuck at calling setState function for page inside of chatBubble widget. Here is my page as MedicBot and chat question code as FirstQuestion. What I do want to do that whenever, user triggers radio tile's on tap condition. It should be trigger setState function in MedicBot, any suggestions?
import 'package:medicte/assets/back_button.dart';
import 'package:medicte/assets/first_question.dart';
class MedicBot extends StatefulWidget {
const MedicBot({Key? key}) : super(key: key);
#override
State<MedicBot> createState() => _MedicBotState();
}
class _MedicBotState extends State<MedicBot> {
late final List<Widget> _messages;
late final List<dynamic> botMessages;
FocusNode _focusNode = FocusNode();
setMainState() {
print('bum');
this.setState(() {});
}
#override
void initState() {
print('bumbeyarag');
botMessages = [
_buildChatBubbles(
widget: SizedBox.shrink(),
text:
'Do you have further medical information you can share? (e.g. lab results)',
userControl: false),
_buildChatBubbles(
widget: FirstQuestion(
focus: _focusNode,
radioButtons: ['1-2 weeks', 'A Month', '1-3 Months', 'Other'],
setMainState: setMainState,
),
text: 'Where do you currently live?',
userControl: false),
_buildChatBubbles(
widget: FirstQuestion(
focus: _focusNode,
radioButtons: [
'Online Consultation',
'Second Opinion',
'A treatment cost',
'Other'
],
setMainState: setMainState,
),
text: 'How soon do you want to get the treatment done?',
userControl: false),
_buildChatBubbles(
widget: FirstQuestion(
focus: _focusNode,
radioButtons: ['Yes', 'No'],
setMainState: () {
setState(() {});
},
),
text: 'What service are you looking for?',
userControl: false),
_buildChatBubbles(
widget: FirstQuestion(
focus: _focusNode,
radioButtons: [],
setMainState: () {
setState(() {});
},
),
text: 'Have you already spoken a doctor?',
userControl: false),
_buildChatBubbles(
text: 'Which treatment are you interested in?',
userControl: false,
widget:
const Text('Enter a treatment name (e.g Hair Transplant, IVF)')),
_buildChatBubbles(
text: 'You are inquiring for',
userControl: false,
widget: FirstQuestion(
radioButtons: const ['Myself', 'For someone else'],
focus: _focusNode,
setMainState: () {
setState(() {});
},
)),
];
_messages = [
const SizedBox(
height: 1,
),
const SizedBox(
height: 10,
)
];
super.initState();
}
final TextEditingController _controller = TextEditingController();
bool value = false;
#override
Widget build(BuildContext context) {
if (botMessages.isNotEmpty) {
_messages.insert(1, botMessages.removeLast());
}
return Scaffold(
bottomSheet: Container(
color: Colors.white30,
child: Padding(
padding: const EdgeInsets.only(bottom: 30, right: 15, left: 15),
child: TextFormField(
focusNode: _focusNode,
controller: _controller,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25),
),
hintText: 'Type your message',
suffixIcon: IconButton(
onPressed: () {
print(_controller.text);
print(_controller.value);
setState(() {
_messages.insert(
1,
_buildChatBubbles(
text: _controller.text,
userControl: true,
widget: const SizedBox.shrink()));
_controller.clear();
});
},
icon: const Icon(Icons.send),
),
),
),
),
),
appBar: AppBar(
leadingWidth: 101,
backgroundColor: Colors.blue.shade300,
leading: Row(
children: [
const BackWardButton(),
ClipRRect(
borderRadius: BorderRadius.circular(1000),
child: Container(
color: Colors.white,
child: Image.asset(
'lib/images/Lovepik_com-401792159-medical-robot.png',
height: 53,
width: 53),
),
),
],
),
title: const Text(
"MedicBot",
style: TextStyle(color: Colors.black54),
),
),
body: SafeArea(
minimum:
const EdgeInsets.only(top: 2, left: 10, right: 10, bottom: 90),
child: ListView.builder(
itemCount: _messages.length,
reverse: true,
itemBuilder: ((context, index) {
return _messages[index];
}),
)));
}
}
class _buildChatBubbles extends StatelessWidget {
bool userControl;
String text;
Widget widget;
_buildChatBubbles(
{required this.widget,
required this.text,
required this.userControl,
super.key});
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 10),
child: Row(
mainAxisAlignment:
userControl ? MainAxisAlignment.end : MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
userControl
? const SizedBox.shrink()
: Container(
margin: const EdgeInsets.only(right: 10),
child: const CircleAvatar(
radius: 20,
backgroundImage: AssetImage(
'lib/images/Lovepik_com-401792159-medical-robot.png'),
),
),
Container(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.4,
maxWidth: MediaQuery.of(context).size.width * 0.6),
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: userControl ? Colors.green.shade300 : Colors.blue.shade300,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 1,
blurRadius: 7,
offset: const Offset(0, 3), // changes position of shadow
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
userControl ? 'You' : 'Medicte Bot',
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 5),
Flexible(
child: Text(
text,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
),
),
),
widget
],
),
),
],
),
);
;
}
}
import 'package:flutter/material.dart';
import 'package:group_button/group_button.dart';
import 'package:medicte/pages/chat_ui.dart';
// ignore: must_be_immutable
class FirstQuestion extends StatefulWidget {
List<String> radioButtons;
FocusNode focus;
void Function() setMainState;
FirstQuestion(
{required this.setMainState,
required this.focus,
required this.radioButtons,
Key? key})
: super(key: key);
#override
State<FirstQuestion> createState() => _FirstQuestionState();
}
class _FirstQuestionState extends State<FirstQuestion> {
late GroupButtonController _radioController;
// ignore: prefer_typing_uninitialized_variables
late final _radioButtons;
#override
void initState() {
_radioButtons = widget.radioButtons;
_radioController = GroupButtonController(
selectedIndexes: [0, 1, 2, 3],
);
super.initState();
}
#override
Widget build(BuildContext context) {
return GroupButton(
controller: _radioController,
isRadio: true,
options: const GroupButtonOptions(groupingType: GroupingType.column),
buttons: _radioButtons,
buttonIndexedBuilder: (selected, index, context) {
return RadioTile(
title: _radioButtons[index],
selected: _radioController.selectedIndex,
index: index,
onTap: () {
print(_radioButtons[index].toString());
widget.setMainState();
_radioController.selectIndex(index);
/* Future.delayed(Duration(seconds: 1), () {
widget.setMainState();
}); */
},
);
},
onSelected: (val, i, selected) {
print('object');
});
}
}
class RadioTile extends StatelessWidget {
const RadioTile({
Key? key,
required this.selected,
required this.onTap,
required this.index,
required this.title,
}) : super(key: key);
final String title;
final int index;
final int? selected;
final VoidCallback onTap;
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(title),
onTap: onTap,
leading: Radio<int>(
groupValue: selected,
value: index,
onChanged: (val) {
print(val);
onTap();
},
),
);
}
}
Try something like this. This is the code snippet of an application of mine. I used StatefulBuilder as the parent of the widgets I want to update and I sent the setState parameter to the widget where I trigger.
import 'package:flutter/material.dart';
class CryptoassetsPage extends StatefulWidget {
const CryptoassetsPage({Key? key}) : super(key: key);
#override
_CryptoassetsPageState createState() => _CryptoassetsPageState();
}
class _CryptoassetsPageState extends State<CryptoassetsPage> {
#override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).backgroundColor,
child: SingleChildScrollView(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
//My other class/widget
return OrderOptions(setState);
}),
),
);
}
}
class OrderOptions extends StatefulWidget {
const OrderOptions(this.setState, {Key? key}) : super(key: key);
final StateSetter setState;
#override
_OrderOptionsState createState() => _OrderOptionsState();
}
class _OrderOptionsState extends State<OrderOptions> {
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
StateSetter setState = widget.setState;
setState(() {});
},
);
}
}

How to add navigation in my Bottom Navigation Bar

I'm new to Flutter, I want to create a navigation bar that can change color when I tap on it. I'm done with that part. Now I'm working on how to navigate to the other page when I tap the navigation bar.
This is my code.
I don't know how to implement the navigation part in my code. I confuse with isSelected and selectedIndex. Hope someone can help me on this and clarify for my better understanding in Flutter.
class BottomNavBar extends StatefulWidget {
#override
State<BottomNavBar> createState() => _BottomNavBarState();
}
class _BottomNavBarState extends State<BottomNavBar> {
int _isSelected = 0;
final List<BottomNavItem> _listBottomNavItems = const [
BottomNavItem(title:'Home', icon: Icons.home),
BottomNavItem(title:'Activity', icon: Icons.receipt),
BottomNavItem(title:'Wallet', icon: Icons.credit_card),
BottomNavItem(title:'Notification', icon: Icons.notifications),
BottomNavItem(title:'Settings', icon: Icons.person),
];
#override
Widget build(BuildContext context) {
return
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(_listBottomNavItems.length,
(index){
return BottomNavItem(
title: _listBottomNavItems[index].title,
icon: _listBottomNavItems[index].icon,
isSelected: _isSelected == index,
onTap: (){
setState((){
_isSelected = index;
});
}
);
})
);
}
}
class BottomNavItem extends StatelessWidget {
final String title;
final IconData icon;
final bool? isSelected;
final Function()? onTap;
const BottomNavItem({
required this.title,
required this.icon,
this.isSelected,
this.onTap
});
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
padding: const EdgeInsets.all(5),
width: 50,
height: 40,
decoration: BoxDecoration(
color: isSelected == true ? Colors.black87: Colors.transparent,
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
Icon(icon, color: isSelected == true ? Colors.white: Colors.black87, size: 17),
const SizedBox(height: 5,),
Text(
title,
style: TextStyle(
fontSize: 7,
fontWeight: FontWeight.bold,
color: isSelected == true ? Colors.white: Colors.black87
),
)
],
)
)
);
}
}
You can add the page in BottomNavItem like this
class BottomNavItem extends StatelessWidget {
final String title;
final IconData icon;
final bool? isSelected;
final Function()? onTap;
final Widget page;
const BottomNavItem({
required this.title,
required this.icon,
required this.page,
this.isSelected,
this.onTap
});
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
onTap!();
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => page,
),
);
},
child: Container(
padding: const EdgeInsets.all(5),
width: 50,
height: 40,
decoration: BoxDecoration(
color: isSelected == true ? Colors.black87: Colors.transparent,
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
Icon(icon, color: isSelected == true ? Colors.white: Colors.black87, size: 17),
const SizedBox(height: 5,),
Text(
title,
style: TextStyle(
fontSize: 7,
fontWeight: FontWeight.bold,
color: isSelected == true ? Colors.white: Colors.black87
),
)
],
)
)
);
}
}
then just add your page in list.
final List<BottomNavItem> _listBottomNavItems = const [
BottomNavItem(title:'Home', icon: Icons.home, page: Home()),
BottomNavItem(title:'Activity', icon: Icons.receipt, page: Activity()),
BottomNavItem(title:'Wallet', icon: Icons.credit_card, page: Wallet()),
BottomNavItem(title:'Notification', icon: Icons.notifications, page: Notification()),
BottomNavItem(title:'Settings', icon: Icons.person, page: Settings()),
];
Hope this works
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(_listBottomNavItems.length,
(index){
return BottomNavItem(
title: _listBottomNavItems[index].title,
icon: _listBottomNavItems[index].icon,
isSelected: _isSelected == index,
onTap: (){
setState((){
_isSelected = index;
if(_listBottomNavItems[index].title == 'Home') {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Home(),
));
} else if(_listBottomNavItems[index].title == 'Activity') {
//write accordingly
}
});
}
);
})
);

Function callback to change text color (just for one) | Flutter

I'm trying to create a SideMenu with different SideMenuItems.
For that I created a new class and want to update the color of Text when the SideMenuItem is clicked. For that I want to transfer the activeState and all that stuff you see in the code below:
The use of my class in the Widget:
bool isActive = false;
...
SideMenuItem(
icon: Icon(
Icons.inbox,
size: 20,
color: isActive ? kPrimaryColor : kGrayColor,
),
activeState: isActive,
title: "Archiv",
toggleActiveState: (activeState) {
setState(() {
isActive = !activeState;
});
},
),
And here is my class:
import 'package:flutter/material.dart';
import 'package:gastronomy/constants.dart';
class SideMenuItem extends StatelessWidget {
// ignore: prefer_const_constructors_in_immutables
SideMenuItem({
Key? key,
required this.activeState,
this.itemCount = 0,
this.showBorder = true,
#required this.icon,
#required this.title,
required this.toggleActiveState,
}) : super(key: key);
final bool activeState;
final bool showBorder;
final int itemCount;
final Icon? icon;
final String? title;
final Function(bool) toggleActiveState;
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: kDefaultPadding),
child: InkWell(
onTap: () {
toggleActiveState(activeState);
},
child: Row(
children: [
const SizedBox(width: 15),
const SizedBox(width: kDefaultPadding / 4),
Expanded(
child: Container(
padding: const EdgeInsets.only(bottom: 15, right: 5),
decoration: showBorder
? const BoxDecoration(
border: Border(
bottom: BorderSide(color: Color(0xFFDFE2EF)),
),
)
: null,
child: Row(
children: [
icon!,
const SizedBox(width: kDefaultPadding * 0.75),
Text(
title!,
style: Theme.of(context).textTheme.button?.copyWith(
color: activeState ? kTextColor : kGrayColor,
),
),
const Spacer(),
// if (itemCount != null) CounterBadge(count: itemCount)
],
),
),
),
],
),
),
);
}
}
I ended up with that pieces of code but well, how you might know, all SideMenuItems change there color when I click one.
I'm pretty new at using this way of code so I would be thankful to all informations you can include into your answer.
One option is to render all the menu items through a map function and compare each item with the selected option, like in the example below:
import 'package:flutter/material.dart';
class MenuExample extends StatefulWidget {
const MenuExample({Key? key}) : super(key: key);
#override
_MenuExampleState createState() => _MenuExampleState();
}
class _MenuExampleState extends State<MenuExample> {
List<String> menuOptions = const ['Item 1', 'Item 2', 'Item 3'];
String selectedOption = '';
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(
backgroundColor: Colors.amber,
child: ListView(
children: menuOptions.map((menuOption) {
return InkWell(
onTap: () => setState(() {
selectedOption = menuOption;
}),
child: MenuItem(
name: menuOption,
isSelected: menuOption == selectedOption,
),
);
}).toList()),
),
);
}
}
class MenuItem extends StatelessWidget {
const MenuItem({Key? key, this.isSelected = false, required this.name})
: super(key: key);
final bool isSelected;
final String name;
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(
name,
style: TextStyle(
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal),
),
);
}
}

How to call a function from stateless Widget that points to state class function?

I am trying to create a responsive chatbot with quick replies. I want to make a button on pressed function call to another class's function. I tried using the callback. But i think i am doing something wrong. Kindly help me.
typedef void mycallback(String label);
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
User? user = FirebaseAuth.instance.currentUser;
UserModel loggedInUser = UserModel();
late DialogFlowtter dialogFlowtter;
final TextEditingController messageController = TextEditingController();
#override
void initState() {
super.initState();
DialogFlowtter.fromFile().then((instance) => dialogFlowtter = instance);
}
#override
Widget build(BuildContext context) {
var themeValue = MediaQuery.of(context).platformBrightness;
Body(
hi: sendMessage,
);
return Scaffold(
backgroundColor: themeValue == Brightness.dark
? HexColor('#262626')
: HexColor('#FFFFFF'),
appBar: AppBar(
//app bar ui
),
actions: [
//list if widget in appbar actions
PopupMenuButton(
icon: Icon(Icons.menu),
color: Colors.blue,
itemBuilder: (context) => [
PopupMenuItem<int>(
value: 0,
child: Text(
"Log out",
style: TextStyle(color: Colors.white),
),
),
],
onSelected: (item) => {logout(context)},
),
],
),
body: SafeArea(
child: Column(
children: [
Expanded(child: Body(messages: messages)),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
child: Row(
children: [
Expanded(
child: TextFormField(
controller: messageController,
style: TextStyle(
color: themeValue == Brightness.dark
? Colors.white
: Colors.black,
fontFamily: 'Poppins'),
decoration: new InputDecoration(
enabledBorder: new OutlineInputBorder(
borderSide: new BorderSide(
color: themeValue == Brightness.dark
? Colors.white
: Colors.black),
borderRadius: BorderRadius.circular(15)),
hintStyle: TextStyle(
color: themeValue == Brightness.dark
? Colors.white54
: Colors.black54,
fontSize: 15,
fontStyle: FontStyle.italic,
),
labelStyle: TextStyle(
color: themeValue == Brightness.dark
? Colors.white
: Colors.black),
hintText: "Type here...",
),
),
),
IconButton(
color: themeValue == Brightness.dark
? Colors.white
: Colors.black,
icon: Icon(Icons.send),
onPressed: () {
sendMessage(messageController.text);
messageController.clear();
},
),
],
),
),
],
),
),
);
}
void sendMessage(String text) async {
if (text.isEmpty) return;
setState(() {
//do main function
});
}
}
The class from where i want to call the function
class Body extends StatelessWidget {
final List<Map<String, dynamic>> messages;
final mycallback? hi;
const Body({
Key? key,
this.messages = const [],
this.buttons = const [],
this.hi,
this.onPressed,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView.separated(
itemBuilder: (context, i) {
var obj = messages[messages.length - 1 - i];
Message message = obj['message'];
bool isUserMessage = obj['isUserMessage'] ?? false;
String label = obj['label'];
return Row(
mainAxisAlignment:
isUserMessage ? MainAxisAlignment.end : MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
_MessageContainer(
message: message,
isUserMessage: isUserMessage,
),
ElevatedButton(
child: Text(label),
onPressed: () => {hi ?? (label)},//This is where i want to call
style: ElevatedButton.styleFrom(
primary: Colors.blueAccent,
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
textStyle: TextStyle(fontWeight: FontWeight.bold)),
),
],
);
},
separatorBuilder: (_, i) => Container(height: 10),
itemCount: messages.length,
reverse: true,
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 20,
),
);
}
}
The code runs without errors but nothing happens when i press the buttons.
This is how I'd implement something like that. You're basically asking for a void as parameter inside your widget. Almost like a TextButton or another widget like that.
You can use this with two stateful widets as well, since you're borrowing the function from one to another.
Also I think this would be done better with provider so I suggest you look into it. (I don't have enough experience with it)
https://pub.dev/packages/provider
class MyHomePage extends StatefulWidget {
const MyHomePage({
Key? key,
}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int x = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('An app'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('$x'),
TestWidget(onTap: () {
setState(() {
x++;
});
})
],
),
),
);
}
}
class TestWidget extends StatelessWidget {
final VoidCallback onTap;
const TestWidget({Key? key, required this.onTap}) : super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
padding: const EdgeInsets.all(20),
color: Colors.blue,
child: Text('test')),
);
}
}
I found the error.
In the class HomeScreen, I missed this line.
child: Body(
messages: messages,
hi: (text) => {sendMessage(text)}, //this line
)
After adding this line, the callback worked fine!

Expected a value of type 'String', but got one of type 'Text'

What is the best way of formatting text enclosed in MdiIcons in flutter and set the text to a particular color in my case white?
Doing it this way I end up with the text appearing as color black(default set by flutter and I want it that way):
[MdiIcons.shieldAccount, Colors.deepPurple, 'COVID-19 Info Center'],
Doing it this way I end up with an error
[MdiIcons.shieldAccount, Colors.deepPurple, Text('COVID-19 Info Center', style: TextStyle(color: Colors.white),)]
the error being thrown is
Expected a value of type 'String', but got one of type 'Text'
The code
class MoreOptionsList extends StatelessWidget {
final List<List> _moreOptionsList = const [
[MdiIcons.shieldAccount, Colors.deepPurple, Text('COVID-19 Info Center', style: TextStyle(color: Colors.white),)],
[MdiIcons.accountMultiple, Colors.cyan, Text('Friends', style: TextStyle(color: Colors.white),)],
[MdiIcons.facebookMessenger, Colors.pinkAccent, Text('Messenger', style: TextStyle(color: Colors.white),)],
[MdiIcons.flag, Colors.orange, Text('Pages', style: TextStyle(color: Colors.white),)],
[MdiIcons.storefront, Colors.lightBlue, Text('Market Place', style: TextStyle(color: Colors.white),)],
[MdiIcons.video, Colors.green, Text('Events', style: TextStyle(color: Colors.white),)],
];
final User currentUser;
const MoreOptionsList({Key key,
#required this.currentUser}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
constraints: BoxConstraints(maxWidth: 280.0),
child: ListView.builder(
itemCount: 1 + _moreOptionsList.length,
itemBuilder: (BuildContext context, int index){
if(index == 0) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: UserCard(user: currentUser),
);
}
final List option = _moreOptionsList [index-1];
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: _Option(icon: option[0], color: option[1], label: option[2]),
);
},
),
);
}
}
class _Option extends StatelessWidget {
final IconData icon;
final Color color;
final String label;
const _Option({Key key,
#required this.icon,
#required this.color,
#required this.label}) : super(key: key);
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () => print(label),
child: Row(
children: [
Icon(icon, size:38.0, color: color,),
const SizedBox(width: 6.0),
Flexible(child: Text(
label, style: const TextStyle(fontSize: 16.0),
overflow: TextOverflow.ellipsis,
),)
],
),
);
}
}
Text is a widget not a string you should color the text inside the widget that required the string so that is mean you can't use widget for string
if you want to get the widget from the list you should change the label type to Text or Widget instead of using String type like this
class _Option extends StatelessWidget {
final IconData icon;
final Color color;
final Text label;
const _Option({Key key,
#required this.icon,
#required this.color,
#required this.label}) : super(key: key);
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () => print(label),
child: Row(
children: [
Icon(icon, size:38.0, color: color,),
const SizedBox(width: 6.0),
Flexible(child: label)
],
),
);
}
}
if the above code didn't help or wasn't good enough you can use this one by adding the String to list then adding it to the Text don't forget to restart the app
final List<List> _moreOptionsList = const [
[Icons.ac_unit, Colors.deepPurple, 'COVID-19 Info Center'],
[Icons.ac_unit, Colors.cyan, 'Friends'],
[Icons.ac_unit, Colors.pinkAccent, 'Messenger'],
[Icons.ac_unit, Colors.orange, 'Pages'],
[Icons.ac_unit, Colors.lightBlue, 'Market Place'],
[Icons.ac_unit, Colors.green, 'Events'],
];
class _Option extends StatelessWidget {
final IconData icon;
final Color color;
final String label;
const _Option(
{Key key,
#required this.icon,
#required this.color,
#required this.label})
: super(key: key);
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () => print(label),
child: Row(
children: [
Icon(
icon,
size: 38.0,
color: color,
),
const SizedBox(width: 6.0),
Flexible(
child: Text(
'$label',
style: const TextStyle(fontSize: 16.0, color: Colors.black),
overflow: TextOverflow.ellipsis,
),
)
],
),
);
}
}