Flutter Widget List on Body Output - flutter

I'm trying to load content (Widget) dynamically (by a index).
However if I not use List all is working as expected:
class _MyHomePageState extends State<MyHomePage> {
final titleController = TextEditingController();
String titolo = '';
late Widget display; //This is the future widget
//List<Widget> display = <Widget>[];
//int displayIndex = 1;
initialize it:
#override
Widget build(BuildContext context) {
//display.add(calculator());
display = calculator();
and use it on body property:
body: display,
When I try to use a list:
class _MyHomePageState extends State<MyHomePage> {
final titleController = TextEditingController();
String titolo = '';
//late Widget display;
List<Widget> display = <Widget>[];
//int displayIndex = 1;
initialize:
#override
Widget build(BuildContext context) {
display.add(calculator());
//display = calculator();
and use it on body property:
body: display.first,
I get this error:
Exception has occurred.
_TypeError (type 'TabContainer' is not a subtype of type 'List' of 'function result')
Please note that TabContainer is the first Widget of calculator():
Widget calculator() => TabContainer(
selectedTextStyle: const TextStyle(
fontFamily: 'ThousandSunny',
This the entire code:
import 'package:cookedcalories/utils.dart';
import 'package:flutter/material.dart';
import 'package:convex_bottom_bar/convex_bottom_bar.dart';
import 'package:tab_container/tab_container.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Cooked Calories & Macros',
theme: ThemeData(
primarySwatch: Colors.pink,
),
home: const MyHomePage(title: 'Cooked Calories & Macros'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final titleController = TextEditingController();
String titolo = '';
//late Widget display;
List<Widget> display = <Widget>[];
//int displayIndex = 1;
#override
void initState() {
titleController.addListener(() => setState(() {}));
super.initState();
}
#override
Widget build(BuildContext context) {
display.add(calculator());
//display = calculator();
return Scaffold(
backgroundColor: Colors.yellow,
bottomNavigationBar: ConvexAppBar(
style: TabStyle.react,
items: const [
TabItem(icon: Icons.info_outline),
TabItem(icon: Icons.receipt_outlined),
TabItem(icon: Icons.calculate_outlined),
TabItem(icon: Icons.monetization_on_outlined),
TabItem(icon: Icons.settings_outlined),
],
initialActiveIndex: 1,
onTap: (int i) => print('click index=$i'),
),
appBar: AppBar(
title: Text(
widget.title,
style: const TextStyle(
fontFamily: 'ThousandSunny',
fontSize: 35,
),
),
),
body: display.first,
);
}
Widget calculator() => TabContainer(
selectedTextStyle: const TextStyle(
fontFamily: 'ThousandSunny',
fontSize: 35,
fontWeight: FontWeight.bold),
unselectedTextStyle: const TextStyle(
fontFamily: 'ThousandSunny',
fontSize: 35,
),
color: Colors.white,
radius: 50,
tabEdge: TabEdge.left,
tabs: const [
'A',
'B',
'C',
],
children: [
Align(
alignment: Alignment.topCenter,
child: SingleChildScrollView(
padding: const EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(5, 30, 0, 0),
child: createTitleField()),
),
const Padding(
padding: EdgeInsets.fromLTRB(10, 30, 5, 0),
child: Image(
width: 50,
height: 50,
image: AssetImage('assets/images/clean.png')),
),
],
),
],
)),
),
const Text('Child 2'),
const Text('Child 3'),
],
);
Widget createTitleField() => TextFormField(
style: const TextStyle(
fontFamily: 'ThousandSunny',
fontSize: 25,
),
controller: titleController,
validator: (value) {
if (value == null || value.trim().isEmpty) {
showSnackBar(
context,
"Attenzione: non hai inserito il Titolo dell'oggetto.",
Colors.pinkAccent.shade400);
return 'Inserisci il Titolo per questo oggetto';
} else if (value.trim().length < 3) {
showSnackBar(
context,
"Attenzione: Il Titolo deve contenere almeno 3 caratteri.",
Colors.pinkAccent.shade400);
return 'Lunghezza minima 3 caratteri';
} else if (value.trim().length > 30) {
showSnackBar(
context,
"Attenzione: Il Titolo non può essere più lungo di 30 caratteri.",
Colors.pinkAccent.shade400);
return 'Lunghezza massima 30 caratteri';
}
titolo = value;
return null;
},
decoration: InputDecoration(
border: const OutlineInputBorder(),
hintText: 'Nome Ricetta',
labelText: 'Nome Ricetta',
labelStyle: const TextStyle(
fontFamily: 'ThousandSunny',
fontSize: 30,
),
hintStyle: const TextStyle(
fontFamily: 'ThousandSunny',
fontSize: 25,
),
suffixIcon: titleController.text.isEmpty
? Container(
width: 0,
)
: IconButton(
onPressed: () => titleController.clear(),
icon: const Icon(Icons.close),
)),
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
);
}

Try Stop project, run flutter pub get and start project again.

Related

Textfield filter in Flutter

I'm a total beginner in Flutter. I try to integrate a textfield filter for my table, but the table is not filtered, but remains unchanged. I added a Provider because I need the current table of Students. after that the Table can't be filtered anymore. Can anyone help me?
here is my code:
class ResultPage extends StatefulWidget {
const ResultPage({Key? key}) : super(key: key);
#override
State<ResultPage> createState() => _ResultPageState();
}
class _ResultPageState extends State<ResultPage> {
List<User>? myData = [];
List<User>? filterData;
_getData(BuildContext context){
myData = Provider.of<LoginService>(context).getStudentsList();
filterData = Provider.of<LoginService>(context).getStudentsList();
}
bool sort = true;
#override
void initState() {
filterData = myData;
super.initState();
}
TextEditingController controller = TextEditingController();
#override
Widget build(BuildContext context) {
_getData(context);
return Scaffold(
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: double.infinity,
child: Theme(
data: ThemeData.light()
.copyWith(cardColor: Theme.of(context).canvasColor),
child: PaginatedDataTable(
sortColumnIndex: 0,
sortAscending: sort,
header: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey,
),
borderRadius: BorderRadius.circular(12)),
child: TextField(
controller: controller,
decoration: const InputDecoration(
hintText: "Enter name to filter"),
onChanged: (value) {
setState(() {
myData = filterData!
.where(
(element) => element.getName.contains(value))
.toList();
});
},
onSubmitted: (value) {
setState(() {
FocusScope.of(context).unfocus();
});
},
),
),
source: RowSource(
myData: myData,
count: myData!.length,
),
rowsPerPage: 16,
columnSpacing: 8,
columns: const [
DataColumn(
label: Text(
"Schüler",
style: TextStyle(
fontWeight: FontWeight.w600, fontSize: 14),
),
),
DataColumn(
label: Text(
"Anzahl Spiele",
style: TextStyle(
fontWeight: FontWeight.w600, fontSize: 14),
),
),
DataColumn(
label: Text(
"Score",
style: TextStyle(
fontWeight: FontWeight.w600, fontSize: 14),
),
),
],
),
)),
const SizedBox(height: 20),
],
),
)
);
}
}
class RowSource extends DataTableSource {
var myData;
final count;
RowSource({
required this.myData,
required this.count,
});
#override
DataRow? getRow(int index) {
if (index < rowCount) {
return recentFileDataRow(myData![index]);
} else {
return null;
}
}
#override
bool get isRowCountApproximate => false;
#override
int get rowCount => count;
#override
int get selectedRowCount => 0;
}
DataRow recentFileDataRow(User data) {
return DataRow(
cells: [
DataCell(Text(data.getName)),
DataCell(Text(data.getSolvedGames().toString())),
DataCell(Text(data.getScore().toString())),
],
);
}
With my code the table always remains unchanged.

The value entered in TextField is inherited

I'm developing a fill-in-the-blanks quiz app.
There are 5 question statements in one quiz, but when I move on to the next question statement, the value entered in the text field remains. Could you please tell me what are the possible causes?
class PlayGame extends StatefulWidget {
final List document;
List correctList = [];
PlayGame({Key? key, required this.document}) : super(key: key);
#override
State<PlayGame> createState() => _PlayGameState();
}
class _PlayGameState extends State<PlayGame> {
int quizNum = 0;
int quizCount = 1;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: Center(
child: Text(
"$quizCount/5",
style: const TextStyle(
fontSize: 25,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold),
),
),
actions: [
Row(
children: [
IconButton(
onPressed: () {
setState(
() {
if (quizNum < 4) {
quizNum += 1;
quizCount += 1;
} else if (quizNum == 4) {
print(widget.correctList.length);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Result()),
);
}
},
);
},
icon: const Icon(
Icons.arrow_circle_right_outlined,
size: 40,
),
),
const SizedBox(
width: 10,
)
],
)
],
automaticallyImplyLeading: false,
),
body: SizedBox(
height: double.infinity,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(bottom: 30.0),
child: TextWithBlanks(
text: widget.document[quizNum],
correctList: widget.correctList),
),
),
),
);
}
}
This is the code I was taught here. Words surrounded by "{}" are BlankWord.
class TextWithBlanks extends StatefulWidget {
final String text;
static final regex = RegExp("(?={)|(?<=})");
List correctList = [];
TextWithBlanks({Key? key, required this.text, required this.correctList})
: super(key: key);
#override
State<TextWithBlanks> createState() => _TextWithBlanksState();
}
class _TextWithBlanksState extends State<TextWithBlanks> {
#override
Widget build(BuildContext context) {
final split = widget.text.split(TextWithBlanks.regex);
return Padding(
padding: const EdgeInsets.only(top: 30.0, right: 30.0, left: 30.0),
child: Text.rich(
TextSpan(
style: const TextStyle(fontSize: 15, height: 3.0),
children: <InlineSpan>[
for (String text in split)
text.startsWith('{')
? WidgetSpan(
child: blankWord(text.substring(1, text.length - 1),
widget.correctList),
)
: TextSpan(text: text),
],
),
),
);
}
}
This is the BlankWord.
class _blankWordState extends State<blankWord> {
#override
Widget build(BuildContext context) {
return SizedBox(
width: widget.answerWidth,
child: TextField(
maxLines: null,
cursorColor: Colors.grey,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
autofocus: false,
maxLength: widget.answerLength + 5,
onChanged: (enterWord) {
widget.value = enterWord;
if (enterWord == widget.answer) {
if (widget.answerBool == false) {
widget.answerBool = true;
widget.correctList.add(widget.answer);
}
} else {
if (widget.answerBool == true) {
widget.answerBool = false;
widget.correctList.remove(widget.answer);
}
}
},
decoration: InputDecoration(
counterText: "",
hintText: widget.answerHint,
hintStyle: const TextStyle(color: Colors.grey, fontSize: 12),
),
),
);
}
}
When you update the page by changing the quiz number also reset the value that you are sending to the blank widget. When the blank widget is updated the widget.value is being updated, and that value stays in the class and when a new blank widget is added the value is being sent to the blank widget again I think
widget.value = enterWord;

I would like to keep multiple TextField to hold values

I am developing a fill-in-the-blanks quiz app.
Each quiz contains 5 sentences and they are arranged by PageView. The sentences are retrieved from a List.
Each sentence is a TextWithBlanks class and they have several BlankWord class (which are TextField).
class TextWithBlanks extends StatefulWidget {
final String text;
static final regex = RegExp("(?={)|(?<=})");
List correctList = [];
TextWithBlanks({Key? key, required this.text, required this.correctList})
: super(key: key);
#override
State<TextWithBlanks> createState() => _TextWithBlanksState();
}
class _TextWithBlanksState extends State<TextWithBlanks> {
#override
Widget build(BuildContext context) {
final split = widget.text.split(TextWithBlanks.regex);
return Padding(
padding: const EdgeInsets.only(top: 30.0, right: 30.0, left: 30.0),
child: Text.rich(
TextSpan(
style: const TextStyle(fontSize: 15, height: 3.0),
children: <InlineSpan>[
for (String text in split)
text.startsWith('{')
? WidgetSpan(
child: blankWord(text.substring(1, text.length - 1),
widget.correctList),
)
: TextSpan(text: text),
],
),
),
);
}
}
class blankWord extends StatefulWidget {
final String answer;
int answerLength = 0;
double answerWidth = 0.0;
String answerHint = "";
List correctList;
String value = "";
bool answerBool = false;
blankWord(this.answer, this.correctList, {Key? key}) : super(key: key) {
answerLength = answer.length;
answerWidth = answerLength * 15.0;
answerHint = answer;
}
#override
State<blankWord> createState() => _blankWordState();
}
class _blankWordState extends State<blankWord> {
Widget build(BuildContext context) {
return SizedBox(
width: widget.answerWidth,
child: TextFormField(
maxLines: null,
cursorColor: Colors.grey,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
autofocus: false,
maxLength: widget.answerLength + 5,
onChanged: (enterWord) {
widget.value = enterWord;
if (enterWord == widget.answer) {
if (widget.answerBool == false) {
widget.answerBool = true;
widget.correctList.add(widget.answer);
}
} else {
if (widget.answerBool == true) {
widget.answerBool = false;
widget.correctList.remove(widget.answer);
}
}
},
decoration: InputDecoration(
counterText: "",
hintText: widget.answerHint,
hintStyle: const TextStyle(color: Colors.grey, fontSize: 12),
),
),
);
}
}
If I enter text in one TextWithBlank BlankWord and then enter text in another TextWithBlank BlankWord, what I entered before disappears.
I want to keep the value in the BlankWord (TextField) of each TextWithBlank. What is the best way to do this?
Thank you.
TextWithBlank is included in the QuizText class.
class PlayGame extends StatefulWidget {
final List document;
List correctList = [];
PlayGame({Key? key, required this.document}) : super(key: key);
#override
State<PlayGame> createState() => _PlayGameState();
}
class _PlayGameState extends State<PlayGame> {
int quizNum = 0;
int quizCount = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: Center(
child: Text(
"$quizCount/5",
style: const TextStyle(
fontSize: 25,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold),
),
),
actions: [
if (quizCount == 5)
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Result(),
),
);
print(widget.correctList.length);
},
child: Row(
children: const [
Text(
"採点する",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
Icon(
Icons.arrow_forward,
size: 20,
),
SizedBox(
width: 10,
)
],
),
)
else
const SizedBox.shrink()
],
automaticallyImplyLeading: false,
),
body: PageView(
onPageChanged: (counter) {
setState(
() {
quizCount = counter + 1;
},
);
},
children: [
QuizText(widget: widget, quizNum: 0),
QuizText(widget: widget, quizNum: 1),
QuizText(widget: widget, quizNum: 2),
QuizText(widget: widget, quizNum: 3),
QuizText(widget: widget, quizNum: 4)
],
),
);
}
}
class QuizText extends StatelessWidget {
const QuizText({
Key? key,
required this.widget,
required this.quizNum,
}) : super(key: key);
final PlayGame widget;
final int quizNum;
#override
Widget build(BuildContext context) {
return Container(
constraints: const BoxConstraints.expand(),
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Card(
child: SizedBox(
height: double.infinity,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(bottom: 30.0),
child: TextWithBlanks(
text: widget.document[quizNum],
correctList: widget.correctList),
),
),
),
),
),
);
}
}
Once the widget is not used, it disposes from widget tree and value lost. You can use state-management property. For now I am using AutomaticKeepAliveClientMixin to preserve the widget .
Changes will be here
class _TextWithBlanksState extends State<TextWithBlanks>
with AutomaticKeepAliveClientMixin {
#override
Widget build(BuildContext context) {
super.build(context);
final split = widget.text.split(TextWithBlanks.regex);
return Padding(
padding: const EdgeInsets.only(top: 30.0, right: 30.0, left: 30.0),
child: Text.rich(
TextSpan(
style: const TextStyle(fontSize: 15, height: 3.0),
children: <InlineSpan>[
for (String text in split)
WidgetSpan(
child: blankWord(
text.substring(1, text.length - 1),
widget.correctList,
),
)
],
),
),
);
}
#override
bool get wantKeepAlive => true;
}

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!

Stateful constrictor Widget in flutter

I am trying to do customized class using stateful widget and I have to use stateful because it have setState function however I want to add property for the class so, when ever I invoke the class I pass the colors I want or store the data I want I did the same for Rassed Button using stateless widget and it is works but for the statefulI have an error that the variable is undefined
I tried to invoke it using widget.borderColor but i have an error that the widget is not defined
here is the code :
class DoseDropDown extends StatefulWidget {
Color borderColor;
Color hintColor;
DoseDropDown({
this.hintColor,
this.borderColor,
});
#override
_DoseDropDownState createState() => _DoseDropDownState();
}
String medicationDose;
List<DropdownMenuItem> getDropDownItem() {
List<DropdownMenuItem> dropDownItems = [];
for (String dose in medcationDose) {
var newItem = DropdownMenuItem(
child: Text(
dose,
style: TextStyle(
here I am trying to use it :
color: hintColor,
and I have error that it is not defined
fontSize: 23, fontWeight: FontWeight.bold,
),
),
value: dose,
);
dropDownItems.add(newItem);
}
return dropDownItems;
}
List<String> medcationDose = [
'مرة واحدة في اليوم',
'مرتان في اليوم',
'ثلاث مرات في اليوم',
'اربعة مرات في اليوم',
'وقت الحاجة'
];
class _DoseDropDownState extends State<DoseDropDown> {
#override
Widget build(BuildContext context) {
return SizedBox(
height: 70,
width: 350,
child: DropdownButtonFormField(
dropdownColor: white,
value: medicationDose,
items: getDropDownItem(),
iconSize: 50,
iconEnabledColor: yellow,
onChanged: (value) {
setState(() {
medicationDose = value;
});
},
decoration: InputDecoration(
prefixIcon: Icon(
MyFlutterApp.pills__2_,
color: yellow,
size: 30,
),
hintText: 'الجرعة',
hintStyle: TextStyle(
fontSize: 30, fontWeight: FontWeight.bold, color: white),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: borderColor,
),
borderRadius: BorderRadius.circular(30.0),
),
),
),
);
}
}
You can copy paste run full code below
In this case, function getDropDownItem() is global and not in class _DoseDropDownState
You can pass hintColor as a parameter
You can in DropdownButtonFormField use widget.hintColor and pass to getDropDownItem
code snippet
List<DropdownMenuItem> getDropDownItem(Color hintColor) {
...
child: DropdownButtonFormField(
dropdownColor: Colors.white,
value: medicationDose,
items: getDropDownItem(widget.hintColor),
working demo
full code
import 'package:flutter/material.dart';
String medicationDose;
List<DropdownMenuItem> getDropDownItem(Color hintColor) {
List<DropdownMenuItem> dropDownItems = [];
for (String dose in medcationDose) {
var newItem = DropdownMenuItem(
child: Text(
dose,
style: TextStyle(
color: hintColor,
fontSize: 23,
fontWeight: FontWeight.bold,
),
),
value: dose,
);
dropDownItems.add(newItem);
}
return dropDownItems;
}
List<String> medcationDose = [
'مرة واحدة في اليوم',
'مرتان في اليوم',
'ثلاث مرات في اليوم',
'اربعة مرات في اليوم',
'وقت الحاجة'
];
class DoseDropDown extends StatefulWidget {
Color borderColor;
Color hintColor;
DoseDropDown({
this.hintColor,
this.borderColor,
});
#override
_DoseDropDownState createState() => _DoseDropDownState();
}
class _DoseDropDownState extends State<DoseDropDown> {
#override
Widget build(BuildContext context) {
return SizedBox(
height: 70,
width: 350,
child: DropdownButtonFormField(
dropdownColor: Colors.white,
value: medicationDose,
items: getDropDownItem(widget.hintColor),
iconSize: 50,
iconEnabledColor: Colors.yellow,
onChanged: (value) {
setState(() {
medicationDose = value;
});
},
decoration: InputDecoration(
prefixIcon: Icon(
Icons.home,
color: Colors.yellow,
size: 30,
),
hintText: 'الجرعة',
hintStyle: TextStyle(
fontSize: 30, fontWeight: FontWeight.bold, color: Colors.white),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.green,
),
borderRadius: BorderRadius.circular(30.0),
),
),
),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DoseDropDown(
hintColor: Colors.brown,
)
],
),
),
);
}
}