Related
I made a simple app where I am using firebase authentication
I used Side drawer in this app
The app work fine on all other tabs but when ever I pressed home button from side drawer instead of going to home screen(initial page route) Login Page comes out and If on the same time I Hot Reload the app then I automatically re-direct to home Screen
2 days ago the app is working currently fine but today this is happening.
Here is my Main.dart file:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
static const myApproute = 'myapproue';
const MyApp({super.key});
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final screen = [
const HomePage(),
AnnoucementScreen(),
const AdminScreen(),
const SettingsScreen(),
];
int currentIndex = 0;
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
pageTransitionsTheme: PageTransitionsTheme(
builders: {
TargetPlatform.android: CustomPageTransitionBuilder(),
},
),
),
home: StreamBuilder(
stream: Login().firebaseAuth.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Scaffold(
body: screen[currentIndex],
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
showUnselectedLabels: false,
selectedItemColor: Colors.black,
unselectedItemColor: Colors.grey,
currentIndex: currentIndex,
// onTap: (value) => setState(() => currentIndex = value),
onTap: (value) {
setState(() {
currentIndex = value;
});
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(
icon: Icon(Icons.event), label: 'Announcement'),
BottomNavigationBarItem(
icon: Icon(Icons.admin_panel_settings), label: 'Admin'),
BottomNavigationBarItem(
icon: Icon(Icons.settings_accessibility_sharp),
label: 'Profile'),
],
),
);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
return const LoginScreen();
}),
routes: {
MyApp.myApproute: (context) => const MyApp(),
LoginScreen.rout: (context) => const LoginScreen(),
SignUpScreen.signUpRout: (context) => const SignUpScreen(),
BabaHassanLifeIntroScreen.babaHassanPageRout: (context) =>
const BabaHassanLifeIntroScreen(),
BabahafizIqbalLifeIntroScreen.babaHafizIqbalRout: (context) =>
const BabahafizIqbalLifeIntroScreen(),
BabaHassanMizajScreen.babaSaiMijazRout: (context) =>
const BabaHassanMizajScreen(),
BabaHassanLifeIncident.babaHassanLifeincident: (context) =>
const BabaHassanLifeIncident(),
BabaHafizIqbalMizajScreen.babaHafizIqbalMizajScreenRoute: (context) =>
const BabaHafizIqbalMizajScreen(),
BabaHafizIqbalLifeIncidentScreen.babaHafizIqbalLifeIncidentScreenRoute:
(context) => const BabaHafizIqbalLifeIncidentScreen(),
TasheerActivitiesScree.tasheerActivitiesScreeRoute: (context) =>
const TasheerActivitiesScree(),
DarbarIntroScreen.darbarIntroScreenRoute: (context) =>
const DarbarIntroScreen(),
ShujraShareefScreen.shujraShareefScreenRoute: (context) =>
const ShujraShareefScreen(),
MusabaEelaafScreen.musabaEelaafScreenRoute: (context) =>
const MusabaEelaafScreen(),
MusabaEelaafBunyadScreen.musbaEelaafBunyadScreenRoute: (context) =>
const MusabaEelaafBunyadScreen(),
BooksScreen.booksScreenRoute: (context) => const BooksScreen(),
SettingMenu.settingMenuRoute: (context) => SettingMenu(),
AdminHome.adminHomeRoute: (context) => AdminHome(),
CreateEvent.createEventRoute: (context) => const CreateEvent(),
SettingMenuAccount.settingMenuAccountRoute: (context) =>
const SettingMenuAccount(),
FeedBackForm.feedBackFormRoute: (context) => const FeedBackForm(),
HomePage.homeRout: (context) => const HomePage(),
},
);
}
}
Here is my sideDrawer.dart file:
class SideDrawer extends StatefulWidget {
const SideDrawer({super.key});
#override
State<SideDrawer> createState() => _SideDrawerState();
}
class _SideDrawerState extends State<SideDrawer> {
var _expanded = false;
var _expandedTwo = false;
//var _expandedThree = false;
var _expandedFive = false;
#override
Widget build(BuildContext context) {
MediaQueryData mediaQueryData;
mediaQueryData = MediaQuery.of(context);
return Drawer(
width: mediaQueryData.size.width * 0.7,
child: ListView(
children: <Widget>[
DrawerHeader(
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
),
gradient: LinearGradient(colors: [
Colors.black,
Color.fromRGBO(255, 243, 18, 3),
], begin: Alignment.topLeft, end: Alignment.bottomRight),
),
child: Padding(
padding: const EdgeInsets.only(top: 70),
child: Column(
children: const [
Text(
"Musaba-Tul-Eelaad",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
textAlign: TextAlign.justify,
),
Text(
"مثابۃ ایلاف",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
textAlign: TextAlign.justify,
),
],
),
),
),
ListTile(
title: const Text(
"Home Page",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 18),
),
onTap: () {
Navigator.of(context).pushReplacementNamed('/');
},
),
const Divider(),
ListTile(
title: const Text(
"Introduction (تعارف)",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 18),
),
trailing: Icon(_expanded ? Icons.expand_less : Icons.expand_more),
onTap: () {
setState(() {
_expanded = !_expanded;
});
},
),
if (_expanded)
Column(
children: [
Padding(
padding: const EdgeInsets.only(right: 20),
child: TextButton(
child: const Text(
'شجرہ شریف',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16),
textAlign: TextAlign.right,
),
onPressed: () {
Navigator.of(context).pushReplacementNamed(
ShujraShareefScreen.shujraShareefScreenRoute);
},
),
),
Padding(
padding: const EdgeInsets.only(right: 20),
child: TextButton(
child: const Text(
'مثابۃ ایلاف',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16),
textAlign: TextAlign.right,
),
onPressed: () {
Navigator.of(context).pushReplacementNamed(
MusabaEelaafScreen.musabaEelaafScreenRoute);
},
),
),
],
),
const Divider(),
ListTile(
title: const Text(
"About Ourself (ہمارے بارے میں)",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 18),
),
trailing:
Icon(_expandedTwo ? Icons.expand_less : Icons.expand_more),
onTap: () {
setState(() {
_expandedTwo = !_expandedTwo;
});
},
),
if (_expandedTwo)
Column(
children: [
Padding(
padding: const EdgeInsets.only(right: 20),
child: ListTile(
title: const Text(
'باباسائیں حسن الدینؒ',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16),
textAlign: TextAlign.center,
),
onTap: () {
Navigator.of(context).pushReplacementNamed(
BabaHassanLifeIntroScreen.babaHassanPageRout);
},
),
),
const Divider(),
Padding(
padding: const EdgeInsets.only(right: 20),
child: ListTile(
title: const Text(
'حافظ سائیں محمداقبالؒ',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16),
textAlign: TextAlign.center,
),
onTap: () {
Navigator.of(context).pushReplacementNamed(
BabahafizIqbalLifeIntroScreen.babaHafizIqbalRout);
}),
),
const Divider(),
Padding(
padding: const EdgeInsets.only(right: 20),
child: TextButton(
child: const Text(
'تشہیر اور سرگرمیاں',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16),
textAlign: TextAlign.right,
),
onPressed: () {
Navigator.of(context).pushReplacementNamed(
TasheerActivitiesScree.tasheerActivitiesScreeRoute);
},
),
),
const Divider(),
Padding(
padding: const EdgeInsets.only(right: 20),
child: TextButton(
child: const Text(
'دربار باباسائیں حسن الدینؒ و حافظ سائیں محمد اقبالؒ',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16),
textAlign: TextAlign.center,
),
onPressed: () {
Navigator.of(context).pushReplacementNamed(
DarbarIntroScreen.darbarIntroScreenRoute);
},
),
),
],
),
const Divider(),
ListTile(
title: const Text(
"Gallery (گیلری)",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 18),
),
// trailing:
// Icon(_expandedThree ? Icons.expand_less : Icons.expand_more),
onTap: () {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: const Text("Attention Required"),
content: const Text(
"The gallery content is currently Under-Development.You will be notified when its ready for you. Please make sure you enable notification to get Future updates"),
actions: [
TextButton(
onPressed: () {
Navigator.of(ctx).pop();
},
child: const Text("Okay"))
],
),
);
// setState(() {
// _expandedThree = !_expandedThree;
// });
},
),
const Divider(),
ListTile(
title: const Text(
"Books (قطب)",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 18),
),
onTap: () {
Navigator.of(context)
.pushReplacementNamed(BooksScreen.booksScreenRoute);
},
),
const Divider(),
ListTile(
title: const Text(
"Cermony (تقریب)",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 18),
),
trailing:
Icon(_expandedFive ? Icons.expand_less : Icons.expand_more),
onTap: () {
setState(() {
_expandedFive = !_expandedFive;
});
},
),
if (_expandedFive)
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 20),
child: TextButton(
child: const Text(
'۱۳رجب۱۴۴۱۔۲۰۱۹',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16),
textAlign: TextAlign.right,
),
onPressed: () => {},
),
)
],
),
],
),
);
}
}
Here is my Login Screen File:
class LoginScreen extends StatefulWidget {
static const rout = '/login-screen';
const LoginScreen({super.key});
#override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final Map<String, String> _loginData = {'email': '', 'password': ''};
GlobalKey topWidgetKey = GlobalKey();
GlobalKey bottomWidgetKey = GlobalKey();
double topWidgetHeight = 0.0;
double bottomWidgetHeight = 0.0;
double spacer = 0.0;
var isLoading = false;
#override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
setState(() {
final topWidgetKeyContextt = topWidgetKey.currentContext;
if (topWidgetKeyContextt != null) {
final box = topWidgetKeyContextt.findRenderObject() as RenderBox;
topWidgetHeight = box.size.height;
}
final bottomWidgetKeyContextt = bottomWidgetKey.currentContext;
if (bottomWidgetKeyContextt != null) {
final box = bottomWidgetKeyContextt.findRenderObject() as RenderBox;
bottomWidgetHeight = box.size.height;
}
spacer = MediaQuery.of(context).size.height -
AppBar().preferredSize.height -
topWidgetHeight -
bottomWidgetHeight -
MediaQuery.of(context).viewPadding.top -
MediaQuery.of(context).viewPadding.bottom;
});
}
});
super.initState();
}
final _emailController = TextEditingController();
final _form = GlobalKey<FormState>();
final _passwordController = TextEditingController();
var visible = true;
final emailVerificationSyntax = RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+");
void _errorDialog(String message) {
showDialog(
context: context,
builder: ((ctx) => AlertDialog(
title: const Text("An Error Accourd"),
content: Text(message),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(ctx).pop();
},
child: const Text("Okay"))
],
)),
);
}
void push() {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (_) => const MyApp(),
),
(route) => false);
}
Future<void> _saveData() async {
final isValid = _form.currentState!.validate();
if (!isValid) {
return;
}
_form.currentState!.save();
setState(() {
isLoading = true;
});
try {
await Login().signInUser(_loginData['email'].toString(),
_loginData['password'].toString(), context);
push();
} catch (e) {
var errorMessage = 'Authentication Failed';
if (e.toString().contains('INVALID_EMAIL')) {
errorMessage = 'The email adress is not valid';
} else if (e.toString().contains('EMAIL_NOT_FOUND')) {
errorMessage = 'No User found with this Email';
} else if (e.toString().contains('INVALID_PASSWORD')) {
errorMessage = 'Invalid Password';
}
_errorDialog(errorMessage);
}
setState(() {
isLoading = false;
});
}
#override
void dispose() {
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color.fromRGBO(255, 243, 18, 3),
body: SingleChildScrollView(
child: Form(
key: _form,
child: Column(children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 90),
child: Image.asset('assets/images/Logo.png'),
),
const SizedBox(
height: 10,
),
const SafeArea(
child: Padding(
padding: EdgeInsets.only(left: 3, right: 250, top: 10),
child: Text(
"Login",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 40),
// textAlign: TextAlign.center,
),
),
),
const Padding(
padding: EdgeInsets.only(left: 20, right: 200, top: 3),
child: Text(
"Please Login to continue",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.normal,
fontSize: 15),
// textAlign: TextAlign.center,
),
),
const SizedBox(
height: 15,
),
Card(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
shadowColor: Colors.grey,
elevation: 10,
child: TextFormField(
controller: _emailController,
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
labelText: 'Email-Address',
prefixIcon: Icon(
(Icons.person),
),
border: OutlineInputBorder(borderSide: BorderSide.none),
),
onSaved: (newValue) {
_loginData['email'] = newValue!;
},
validator: (value) {
if (!emailVerificationSyntax.hasMatch(value as String)) {
return "Incorrect Email-Adress Syntax";
}
if (value.isEmpty) {
return 'Please Enter Your Email Adress';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
Card(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
shadowColor: Colors.grey,
elevation: 10,
child: TextFormField(
controller: _passwordController,
obscureText: visible,
keyboardType: TextInputType.streetAddress,
decoration: InputDecoration(
labelText: 'Password',
prefixIcon: const Icon(
(Icons.password),
),
suffixIcon: IconButton(
onPressed: () {
setState(() {
visible = !visible;
});
},
icon: const Icon(Icons.visibility)),
border: const OutlineInputBorder(borderSide: BorderSide.none),
),
validator: (value) {
if (value!.isEmpty) {
return "Please Enter Your Passowrd";
}
return null;
},
onSaved: (newValue) {
_loginData['password'] = newValue!;
},
),
),
const SizedBox(
height: 15,
),
isLoading
? const CircularProgressIndicator()
: ElevatedButton(
onPressed: () => _saveData(),
style: ElevatedButton.styleFrom(
// backgroundColor: Color.fromARGB(255, 246, 214, 4)),
backgroundColor: Colors.white),
child: const Text(
'Login',
style: TextStyle(
color: Colors.black,
fontSize: 30,
fontWeight: FontWeight.normal,
),
),
),
const SizedBox(
height: 100,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Padding(
padding: EdgeInsets.only(bottom: 20),
child: Text(
"Don't have an account?",
style: TextStyle(color: Colors.black, fontSize: 18),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 20),
child: TextButton(
onPressed: () {
Navigator.of(context)
.pushReplacementNamed(SignUpScreen.signUpRout);
},
child: const Text(
"Sign Up",
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.bold),
)),
)
],
)
]),
),
),
);
}
}
This is my project I m currently working on and now when the time comes to deliver it this is happen I tried a-lot but not figure it out.
I am getting this error "The instance member 'setState' cant be accessed in an initializer" here :
This is the full code :
class insertLossEvent extends StatefulWidget {
#override
State<insertLossEvent> createState() => _insertLossEventState();
}
class _insertLossEventState extends State<insertLossEvent> {
static final field_1Controller = TextEditingController();
static final field_4Controller = TextEditingController();
void _sendLogin() async {
var newMessage = await (ReadCache.getString(key: 'cache1'));
var map = <String, dynamic>{
"Field_1": field_1Controller.text,
"Field_4": field_4Controller.text,
"table_id": "25510",
"form_type": "2",
};
var res = await http.post(
Uri.parse("http://192.168.1.4:8080/HongLeong/SET_FORM_REQUEST.do"),
headers: {HttpHeaders.cookieHeader: newMessage},
body: map,
);
final data = jsonDecode(res.body);
print(data);
}
int _selectedIndex = 0;
void _navigateBottomBar(int index) {
setState(() {
_selectedIndex = index;
});
}
static List<String> orgUnit = [
'M1',
'M100138',
'M100078',
'M100108',
'M100069',
'M100118',
'M100071',
'M100150'
];
static String valueChoose;
final List<Widget> _pages = [
Container(
child: SingleChildScrollView(
child: Column(
children: [
//Main Info
ListTileTheme(
tileColor: Colors.grey,
child: ExpansionTile(
title: Text('Main Info',
style: GoogleFonts.poppins(
textStyle: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 20,
))),
children: [
//Fields
ListTileTheme(
tileColor: Colors.white,
child: ListTile(
title: Text(
'Title : ',
style: GoogleFonts.poppins(
textStyle: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
),
),
ListTileTheme(
tileColor: Colors.white,
child: ListTile(
title: Container(
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(color: Colors.blueGrey),
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
),
controller: field_1Controller,
style: GoogleFonts.poppins(
textStyle: const TextStyle(
fontWeight: FontWeight.normal,
fontSize: 20,
),
),
),
),
),
),
),
ListTileTheme(
tileColor: Colors.white,
child: ListTile(
title: Text(
'Organization Unit : ',
style: GoogleFonts.poppins(
textStyle: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
),
),
ListTileTheme(
tileColor: Colors.white,
child: ListTile(
title: Container(
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(color: Colors.blueGrey),
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: DropdownButton<String>(
value: valueChoose,
onChanged: (newValue){
setState(() {
valueChoose = newValue;
});
},
items: orgUnit.map((valueItem) {
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
),
),
),
),
),
],
),
),
],
),
),
),
Container(
child: SingleChildScrollView(
child: Column(
children: [
//Shariah Details
ListTileTheme(
tileColor: Colors.grey,
child: ExpansionTile(
title: Text('Shariah Details',
style: GoogleFonts.poppins(
textStyle: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 20,
))),
children: [
//Fields
],
),
),
],
),
),
)
];
In the best case scenario, I'd like to retain the code as this, but if you know of any improvements, please let me know.
How can I make it better? & what causes it to take place?
Thank You
to solve the problem, just add the pages List in the build Function and add return Container();
#override
Widget build(BuildContext context) {
final List<Widget> _pages = [
....
];
return Container();
}
Define pages like
List<Widget> _pages = [];
Then in initstate add values to it
_pages = [// add values here
];
setState((){});
The issue is that you tried adding set state when the codes are initialising. Adding it in initatate will not theow this error
Using late keyword will fix this issue like
late final List<Widget> _pages = [
But I will suggest to use method instead of variables in this case. Using variable doesn't get update context until you reassign the variable.
Do like this is better
List<Widget> _pages(BuildContext context) => [
I created dropdown in TextFormField in flutter, i successfully loaded list (bankDataList) into dropdown which is dynamic list. Data is showing into dropdown list. But i have a problem to assign
"value : _bankChoose" into DropDownButton , it is not updating into TextFormField. I am using icon and text, please see screenshot.
String _bankChoose;
List<BankListDataModel> bankDataList;
Container(
margin: EdgeInsets.only(left: 15, top: 10, right: 15),
child: FormField<String>(
builder: (FormFieldState<String> state) {
return InputDecorator(
decoration: InputDecoration(
contentPadding:
EdgeInsets.fromLTRB(12, 10, 20, 20),
// labelText: "hi",
// labelStyle: textStyle,
// labelText: _dropdownValue == null
// ? 'Where are you from'
// : 'From',
errorText: _errorBank,
errorStyle: TextStyle(
color: Colors.redAccent, fontSize: 16.0),
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10.0))),
child: DropdownButtonHideUnderline(
child: DropdownButton<BankListDataModel>(
style: TextStyle(
fontSize: 16,
color: text_gray_color,
fontFamily: "verdana_regular",
),
hint: Text(
"Select Bank",
style: TextStyle(
color: text_gray_color,
fontSize: 16,
fontFamily: "verdana_regular",
),
),
value: _bankChoose,
isExpanded: true,
isDense: true,
onChanged: (BankListDataModel newValue) {
setState(() {
_bankChoose = newValue.bank_name;
});
},
items: bankDataList
.map<DropdownMenuItem<BankListDataModel>>(
(BankListDataModel valueItem) {
return DropdownMenuItem(
value: valueItem,
child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
new CircleAvatar(
backgroundImage: new NetworkImage(
valueItem.bank_logo),
),
// Icon(valueItem.bank_logo),
SizedBox(
width: 15,
),
Text(valueItem.bank_name),
],
),
);
}).toList(),
),
),
);
},
),
),
You want to choose drop down item of type BankListDataModel, then your _bankChoose variable should be of type BankListDataModel.
Try this one,
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
//String _bankChoose;
BankListDataModel _bankChoose;
List<BankListDataModel> bankDataList=[
BankListDataModel("SBI","https://www.kindpng.com/picc/m/83-837808_sbi-logo-state-bank-of-india-group-png.png"),
BankListDataModel("HDFC","https://www.pngix.com/pngfile/big/12-123534_download-hdfc-bank-hd-png-download.png"),
BankListDataModel("ICICI","https://www.searchpng.com/wp-content/uploads/2019/01/ICICI-Bank-PNG-Icon-715x715.png"),
//BankListDataModel("Canara","https://bankforms.org/wp-content/uploads/2019/10/Canara-Bank.png")
];
#override
void initState() {
super.initState();
_bankChoose = bankDataList[0];
}
void _onDropDownItemSelected(BankListDataModel newSelectedBank) {
setState(() {
_bankChoose = newSelectedBank;
});
}
#override
Widget build(BuildContext context) {
return
Scaffold(
body: Form(
child: Center(
child: Container(
margin: EdgeInsets.only(left: 15, top: 10, right: 15),
child: FormField<String>(
builder: (FormFieldState<String> state) {
return InputDecorator(
decoration: InputDecoration(
contentPadding:
EdgeInsets.fromLTRB(12, 10, 20, 20),
// labelText: "hi",
// labelStyle: textStyle,
// labelText: _dropdownValue == null
// ? 'Where are you from'
// : 'From',
errorText: "Wrong Choice",
errorStyle: TextStyle(
color: Colors.redAccent, fontSize: 16.0),
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10.0))),
child: DropdownButtonHideUnderline(
child: DropdownButton<BankListDataModel>(
style: TextStyle(
fontSize: 16,
color: Colors.grey,
fontFamily: "verdana_regular",
),
hint: Text(
"Select Bank",
style: TextStyle(
color: Colors.grey,
fontSize: 16,
fontFamily: "verdana_regular",
),
),
items: bankDataList
.map<DropdownMenuItem<BankListDataModel>>(
(BankListDataModel value) {
return DropdownMenuItem(
value: value,
child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
new CircleAvatar(
backgroundImage: new NetworkImage(
value.bank_logo),
),
// Icon(valueItem.bank_logo),
SizedBox(
width: 15,
),
Text(value.bank_name),
],
),
);
}).toList(),
isExpanded: true,
isDense: true,
onChanged: (BankListDataModel newSelectedBank) {
_onDropDownItemSelected(newSelectedBank);
},
value: _bankChoose,
),
),
);
},
),
),
),
),
);
}
}
class BankListDataModel{
String bank_name;
String bank_logo;
BankListDataModel(this.bank_name,this.bank_logo);
}
sorry for formatting of images.
One way would be to use a TextEditingController and assign is to your TextField with controller: textEditingController for example
final textEditingController = TextEditingController();
This is my code and I tried to print the value in my console to figure if it is work and it's correctly printed but it dose not show in the text Filed. When I chose the hint text disappear but no thing show also I changed the Icon (arrow) size but when I click on any part of it, no response until I click in the corner
String _medicationDesc;
List<DropdownMenuItem> getDropDownItem() {
List<DropdownMenuItem> dropDownItems = [];
for (String dose in medcationDose) {
var newItem = DropdownMenuItem(
child: Text(
dose,
style: textStyle1,
),
value: dose,
);
dropDownItems.add(newItem);
}
return dropDownItems;
}
List<String> medcationDose = [
'مرة واحدة في اليوم',
'مرتان في اليوم',
'ثلاث مرات في اليوم',
'اربعة مرات في اليوم',
'وقت الحاجة'
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(backgroundColor: nave),
body: SingleChildScrollView(
child: Container(
margin: EdgeInsets.fromLTRB(0.0, 30, 0, 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
SizedBox(
height: 50,
width: 350,
child: DropdownButtonFormField(
value: _medicationDose,
items: getDropDownItem(),
iconSize: 50,
iconEnabledColor: white,
onChanged: (value) {
setState(() {
_medicationDose = value;
});
},
decoration: InputDecoration(
hintText: 'الجرعة',
),
),
try this
List<String> languageList = ['EN', 'ES', 'FR'];
var selectedValue;
DropdownButtonHideUnderline(
child: DropdownButtonFormField<String>(
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.transparent))),
dropdownColor: CustomColors.black,
value:
selectedValue == null ? languageList[0] : selectedValue,
style: robotoStyle(
color: CustomColors.white,
fontSize: 10),
icon: Icon(
Icons.keyboard_arrow_down,
color: CustomColors.white,
),
isExpanded: true,
items: languageList.map((item) {
return DropdownMenuItem<String>(
value: item,
child: new Text(item,
style: robotoStyle(
color: CustomColors.white,
fontSize: 10)),
);
}).toList(),
onChanged: (value) {
selectedValue = value;
S.load(Locale(selectedValue));
print(selectedValue);
},
),
)
i made a class for you, you can call it anywhere may be it will help you
class DropDownClass extends StatelessWidget {
var values;
var hint;
List list = new List();
Color underLineColor;
Color dropDownColor;
Color textColor;
DropDownClass({this.values,
this.list,this.hint,this.underLineColor,this.dropDownColor,this.textColor});
#override
Widget build(BuildContext context) {
return DropdownButtonHideUnderline(
child: DropdownButtonFormField<String>(
value: values,
dropdownColor: dropDownColor??Colors.white,
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: underLineColor??Colors.grey[800],
width: 1.0,
),
)
),
style: TextStyle(
color: textColor??Colors.black,
fontWeight: FontWeight.w400,
fontSize: 15),
isExpanded: true,
icon: Icon(
Icons.keyboard_arrow_down,
color: Colors.white,
),
hint: Text(hint,
style: TextStyle(
color:Colors.white,
fontWeight: FontWeight.w400,
fontSize:15)),
items: list.map((item) {
return DropdownMenuItem<String>(
value: item,
child: new Text(item,
style: TextStyle(
color:Colors.black,
fontWeight: FontWeight.w400,
fontSize:15)),
);
}).toList(),
onChanged: (value) {
values = value;
print(values);
},
),
);
}
}
I am building a form using the "Flutter Form Builder" package 4.0.2 and trying to add two fields where users enter "tags" via the "material_tag_editor" package 0.0.6
The Problem: when then form is submitted by pressing the "Post" button, neither of the data submitted for those "tag" form fields (Q1 or Q3) is included (see screenshot of the console below).
Notice the line "flutter: {qFour: 30, qFive: sample answer to q5, qTen: sample answer to q10}" - neither Q1 nor Q3 are included (I added their data in separate print statements, so you see them in the console - look for the >>> lines).
Here are screenshots of the form with sample tags entered (iPhone simulator screenshot), and the bottom of the form with the button:
Here's the code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:streakers_journal_beta/screens/reviews_screen.dart';
import 'package:streakers_journal_beta/screens/welcome_screen.dart';
import 'package:streakers_journal_beta/models/user.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
// BEGIN code from material_tag_editor
import 'package:material_tag_editor/tag_editor.dart';
import 'package:material_tag_editor/tag_editor_layout_delegate.dart';
import 'package:material_tag_editor/tag_layout.dart';
import 'package:material_tag_editor/tag_render_layout_box.dart';
// END code from material_tag_editor
//import 'dart:html';
//import 'dart:convert';
// This is the stateful widget that the main application instantiates, per https://api.flutter.dev/flutter/widgets/Form-class.html
class SandboxWriteReviewScreen extends StatefulWidget {
// BEGIN code from material_tag_editor
final String title = 'Material Tag Editor Demo';
// END code from material_tag_editor
#override
_SandboxWriteReviewScreenState createState() =>
_SandboxWriteReviewScreenState();
}
// This is the private State class that goes with WriteReviewScreen
class _SandboxWriteReviewScreenState extends State<SandboxWriteReviewScreen> {
var data;
AutovalidateMode autovalidateMode = AutovalidateMode.always;
bool readOnly = false;
bool showSegmentedControl = true;
//final _newFormbuilderKey = GlobalKey<FormState>();
final _newnewFormbuilderKey = GlobalKey<FormBuilderState>();
// above "GlobalKey" lets us generate a unique, app-wide ID that we can associate with our form, per https://fluttercrashcourse.com/blog/realistic-forms-part1
final ValueChanged _onChanged = (val) => print(val);
// BEGIN related to FormBuilderTextField in form below
final _ageController = TextEditingController(text: '45');
bool _ageHasError = false;
// END related to FormBuilderTextField in form below
String qEleven;
String qTwelve;
// BEGIN code from material_tag_editor
List<String> qOne = [];
final FocusNode _focusNode = FocusNode();
onDelete(index) {
setState(() {
qOne.removeAt(index);
});
}
// below = reiteration for cons
List<String> qThree = [];
//final FocusNode _focusNode = FocusNode();
uponDelete(index) {
// NOTE: "uponDelete" for cons vs. "onDelete" for pros
setState(() {
qThree.removeAt(index);
});
}
// END code from material_tag_editor
//final _user = User();
List<bool> isSelected;
int starIconColor =
0xffFFB900; // was 0xffFFB900; 0xffD49428 is from this image: https://images.liveauctioneers.com/houses/logos/lg/bartonsauction550_large.jpg?auto=webp&format=pjpg&width=140
#override
void initState() {
//isSelected = [true, false];
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
Padding(
padding: EdgeInsets.only(right: 12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
icon: Icon(Icons.keyboard_backspace),
onPressed: () {
Navigator.pop(context);
},
),
Text(
'back',
style: TextStyle(
fontSize: 7,
),
),
],
),
),
],
leading: Icon(
Icons.rate_review,
color: Colors.black54,
),
title: Column(
children: [
Text(
'SANDBOX Write a Review',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
SizedBox(
height: 6.0,
),
Text(
'flutter_form_builder ^4.0.2',
style: TextStyle(
color: Colors.limeAccent,
fontSize: 14,
),
),
SizedBox(
height: 6.0,
),
],
),
// BEGIN appBar gradient code, per https://medium.com/flutter-community/how-to-improve-your-flutter-application-with-gradient-designs-63180ba96124
flexibleSpace: Container(
decoration: BoxDecoration(
color: Colors.indigoAccent,
),
),
backgroundColor: Colors.white,
centerTitle: false,
),
body: SingleChildScrollView(
child: Container(
child: Builder(
builder: (context) => FormBuilder(
// was "builder: (context) => Form("
key: _newnewFormbuilderKey,
initialValue: {
'date': DateTime.now(),
},
child: Padding(
padding: const EdgeInsets.all(14.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 12.0,
),
RichText(
text: TextSpan(
style: TextStyle(
color: Colors.blue,
),
children: <TextSpan>[
TextSpan(
text:
'Q1 via TagEditor', // was 'What are 3 good or positive things about the house, property or neighborhood?', // [ 1 ]
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
),
TextSpan(
text: ' (optional)',
style: TextStyle(
fontWeight: FontWeight.normal,
fontStyle: FontStyle.italic,
fontSize: 14.0,
color: Colors.black54,
), // was 'misleading or inaccurate?',
),
],
),
),
// BEGIN code from material_tag_editor
Padding(
padding: const EdgeInsets.only(top: 16.0),
child: TagEditor(
length: qOne.length,
delimiters: [
','
], // was delimiters: [',', ' '], Also tried "return" ('\u2386',) and '\u{2386}'
hasAddButton: true,
textInputAction: TextInputAction
.next, // moves user from one field to the next!!!!
autofocus: false,
maxLines: 1,
// focusedBorder: OutlineInputBorder(
// borderSide: BorderSide(color: Colors.lightBlue),
// borderRadius: BorderRadius.circular(20.0),
// ),
inputDecoration: const InputDecoration(
// below was "border: InputBorder.none,"
isDense: true,
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(20.0),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.lightBlue),
borderRadius: const BorderRadius.all(
const Radius.circular(20.0),
),
// above is per https://github.com/flutter/flutter/issues/5191
),
labelText: 'separate, with, commas',
labelStyle: TextStyle(
fontStyle: FontStyle.italic,
backgroundColor:
Color(0x65dffd02), // was Color(0xffDDFDFC),
color: Colors.black87, // was Color(0xffD82E6D),
fontSize: 14,
),
),
onTagChanged: (value) {
setState(() {
qOne.add(value);
});
},
tagBuilder: (context, index) => _Chip(
index: index,
label: qOne[index],
onDeleted: onDelete,
),
),
),
// END code from material_tag_editor
SuperDivider(),
// END Chips Input
RichText(
text: TextSpan(
style: TextStyle(
color: Colors.blue,
),
children: <TextSpan>[
TextSpan(
text:
'Q3 via TagEditor (skipped Q2, for simplicity)', // [ 2 ] was 'List up to 3 negatives, or things you don’t like, about the house, property or neighborhood:',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
),
TextSpan(
text: '(optional)', // was text: '\n(optional)',
style: TextStyle(
fontWeight: FontWeight.normal,
fontStyle: FontStyle.italic,
fontSize: 14.0,
backgroundColor:
Color(0x70DDFDFC), // was Color(0x30F8A0A2),
color: Colors.black54, // was Color(0xffD82E6D),
//color: Colors.black54,
), // was 'misleading or inaccurate?',
),
],
),
),
// BEGIN code from material_tag_editor
Padding(
padding: const EdgeInsets.only(top: 16.0),
child: TagEditor(
length: qThree.length,
delimiters: [','], // was delimiters: [',', ' '],
hasAddButton: true,
textInputAction: TextInputAction
.next, // moves user from one field to the next!!!!
autofocus: false,
maxLines: 1,
// focusedBorder: OutlineInputBorder(
// borderSide: BorderSide(color: Colors.lightBlue),
// borderRadius: BorderRadius.circular(20.0),
// ),
inputDecoration: const InputDecoration(
// below was "border: InputBorder.none,"
isDense: true,
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(20.0),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.lightBlue),
borderRadius: const BorderRadius.all(
const Radius.circular(20.0),
),
// above is per https://github.com/flutter/flutter/issues/5191
),
labelText: 'separate, with, commas',
labelStyle: TextStyle(
fontStyle: FontStyle.italic,
backgroundColor:
Color(0x65dffd02), // was Color(0xffDDFDFC),
color: Colors.black87, // was Color(0xffD82E6D),
fontSize: 14,
),
),
onTagChanged: (value) {
setState(() {
qThree.add(value);
});
},
tagBuilder: (context, index) => _Chip(
index: index,
label: qThree[index],
onDeleted: uponDelete,
),
),
),
// END code from material_tag_editor
SuperDivider(),
RichText(
text: TextSpan(
style: TextStyle(
color: Colors.blue,
),
children: <TextSpan>[
TextSpan(
text:
'Q4 - via FormBuilder\'s FormBuilderRadioGroup', // [ 3 ]
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
),
TextSpan(
text: ' (required)',
style: TextStyle(
fontWeight: FontWeight.normal,
fontStyle: FontStyle.italic,
fontSize: 14.0,
color: Colors.red[700],
), // was 'misleading or inaccurate?',
),
],
),
),
FormBuilderRadioGroup(
name: 'qFour',
decoration: const InputDecoration(
border: InputBorder.none,
labelStyle: TextStyle(fontStyle: FontStyle.italic),
),
wrapVerticalDirection: VerticalDirection.down,
// orientation: GroupedRadioOrientation.vertical,
orientation: OptionsOrientation.vertical,
onChanged: _onChanged,
options: [
FormBuilderFieldOption(
value: '0', child: Text('Never')),
FormBuilderFieldOption(
value: '30', child: Text('Within the last month')),
FormBuilderFieldOption(
value: '180',
child: Text('Within the last 6 months')),
FormBuilderFieldOption(
value: '181',
child: Text('More than 6 months ago')),
],
),
SuperDivider(),
Center(
child: RichText(
text: TextSpan(
style: TextStyle(
color: Colors.blue,
),
children: <TextSpan>[
TextSpan(
text:
'Q5 - via FormBuilder\'s FormBuilderTextField', // [ 4 ]
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
),
TextSpan(
text: ' (optional)',
style: TextStyle(
fontWeight: FontWeight.normal,
fontStyle: FontStyle.italic,
fontSize: 14.0,
color: Colors.black54,
), // was 'misleading or inaccurate?',
),
],
),
),
),
GavTextField(
maxCharLength: 200,
fieldAttribute: 'qFive',
fieldLabelText: '',
),
SuperDivider(),
RichText(
text: TextSpan(
style: TextStyle(
color: Colors.blue,
),
children: <TextSpan>[
TextSpan(
text:
'Q10 - via FormBuilder\'s FormBuilderTextField (skipped Q6 - Q9, for simplicity)', // [ 9 ]
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
),
TextSpan(
text: ' (optional)',
style: TextStyle(
fontWeight: FontWeight.normal,
fontStyle: FontStyle.italic,
fontSize: 14.0,
color: Colors.black54,
), // was 'misleading or inaccurate?',
),
],
),
),
GavTextField(
maxCharLength: 1200,
fieldAttribute: 'qTen',
fieldLabelText:
'Be honest & kind.', // was 'Be honest, but kind.',
),
SuperDivider(),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.purple,
padding: EdgeInsets.symmetric(
horizontal: 50, vertical: 20),
textStyle: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold)),
onPressed: () {
_newnewFormbuilderKey.currentState.save();
if (_newnewFormbuilderKey.currentState
.validate()) {
print(_newnewFormbuilderKey.currentState.value);
print(
' >>> Q1\'s value via separate print: {$qOne}',
);
print(
' >>> Q3\'s value via separate print: {$qThree}',
);
} else {
print("validation failed");
}
},
child: Text(
'Post',
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
],
),
),
SizedBox(
height: 200.0,
),
],
),
),
),
),
),
),
);
}
}
class GavTextField extends StatelessWidget {
GavTextField(
{#required this.maxCharLength,
#required this.fieldAttribute,
#required this.fieldLabelText});
int maxCharLength;
String fieldAttribute;
String fieldLabelText;
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 16.0),
child: FormBuilderTextField(
name: '$fieldAttribute',
// BEGIN countdown to max number of characters, per https://stackoverflow.com/a/64035861/1459653
maxLength: maxCharLength,
maxLines: null,
buildCounter: (
BuildContext context, {
int currentLength,
int maxLength,
bool isFocused,
}) {
return Text(
'${maxLength - currentLength}',
);
},
// END countdown to max number of characters, per https://stackoverflow.com/a/64035861/1459653
decoration: InputDecoration(
labelText:
'$fieldLabelText', // was " Separate items, with, commas",
//counterText: _textController.text.length.toString(),
labelStyle: TextStyle(
fontSize: 12.5,
fontStyle: FontStyle.italic,
),
//helperText: 'Separate, with, commas',
//floatingLabelBehavior: ,
// filled: true,
// fillColor: Colors.lightBlue.withOpacity(0.05),
// BEGIN change border if focus
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.lightBlue),
borderRadius: BorderRadius.circular(20.0),
),
// END change border if focus
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
borderSide: BorderSide(),
),
),
textInputAction:
TextInputAction.next, // moves user from one field to the next!!!!
autofocus:
false, // on screen load, first text field is already active - user can just start typing
),
);
}
} //</formstate>`
var alertStyle = AlertStyle(
animationType: AnimationType.fromTop,
isCloseButton: true,
isOverlayTapDismiss: true,
descTextAlign: TextAlign.start,
alertBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
side: BorderSide(
color: Colors.grey,
),
),
titleStyle: TextStyle(
fontWeight: FontWeight.normal,
fontStyle: FontStyle.italic,
fontSize: 16,
color: Colors.black54,
),
alertAlignment: Alignment.topCenter,
);
// BEGIN code from material_tag_editor
class _Chip extends StatelessWidget {
const _Chip({
#required this.label,
#required this.onDeleted,
#required this.index,
});
final String label;
final ValueChanged<int> onDeleted;
final int index;
#override
Widget build(BuildContext context) {
return Chip(
backgroundColor: Colors.blueGrey.shade100,
labelPadding: const EdgeInsets.only(left: 8.0),
label: Text(label),
deleteIcon: Icon(
Icons.cancel_rounded, // was "Icons.close,"
size: 18,
),
onDeleted: () {
onDeleted(index);
},
);
}
}
// END code from material_tag_editor
class SuperDivider extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
top: 4.0,
bottom: 4.0,
),
child: const Divider(
color: Colors.white70,
height: 30,
thickness: 0.1,
indent: 0,
endIndent: 0,
),
);
}
}
Flutter form builder assumes that only form children's will be used which automatically updates ancestor form whenever their value is changed. But since tag builder is not a form widget, you can do two things -
Wrap these widgets inside a new form widget, whose responsibility will be to only send updates to the ancestor form and render its child.
You can do something like
class GenericFormWidget<T> extends StatefulWidget {
GenericFormWidget({
Key key,
#required this.attribute,
#required this.builder,
}) : super(key: key);
final String attribute;
final Function(BuildContext, Function(T value)) builder;
#override
Widget build(BuildContext context) {
return widget.builder(context, _updateValue);
}
void _updateValue(T value) =>
_formState.setAttributeValue(widget.attribute, value);
}
Instead of using flutter form builder, you can have use Flutter form and create your own field UI using material widgets. This will be costly for you since you will need to migrate existing fields too.