Related
I'm fairly new to Flutter and I have a page where I take in two inputs in a search fieldstone them in different variables(_selectedYear and _selectedSem) and based on the inputs I create a url.
On creating the two search fields and running it , if I input in the second field before the first one, I have no error but if I input in the first field before the second field this error pops up.
This widget has been unmounted, so the State no longer has a context (and should be
considered defunct). Consider canceling any active work during dispose or using the getter mounted to determine if the state is still active.
Here's a screenshot of the page:
Here is the code.
class _TestrState extends State<Testr> {
String _selectedYear;
String _selectedSem;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.white,
title: const Text(
'Testr',
style: TextStyle(
color: Colors.black,
),
),
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.bottomRight,
colors: [Colors.green, Colors.limeAccent])),
),
),
body: Container(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
height: MediaQuery.of(context).size.height * 0.64,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Padding(
padding: EdgeInsets.all(20.0),
child: Text(
'Select a Year',
style: TextStyle(fontSize: 16, color: Colors.blueGrey),
),
),
Container(
width: double.infinity,
margin: const EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
blurRadius: 10,
offset: const Offset(0, 10),
),
],
),
child: SearchField(
hint: 'Search for Year',
searchInputDecoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.blueGrey.shade200,
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 2,
color: Colors.blue.withOpacity(0.8),
),
borderRadius: BorderRadius.circular(10),
),
),
maxSuggestionsInViewPort: 4,
itemHeight: 50,
suggestionsDecoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
onTap: (value) {
setState(() {
_selectedYear = value;
});
if (kDebugMode) {
print(value);
}
},
suggestions: const [
'Year One',
'Year Two',
'Year Three',
'Year Four',
],
),
),
const Padding(
padding: EdgeInsets.all(20.0),
child: Text(
'Select a Semester',
style: TextStyle(fontSize: 16, color: Colors.blueGrey),
),
),
Container(
width: double.infinity,
margin: const EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
blurRadius: 10,
offset: const Offset(0, 10),
),
],
),
child: SearchField(
hint: 'Search for Semester',
searchInputDecoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.blueGrey.shade200,
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 2,
color: Colors.blue.withOpacity(0.8),
),
borderRadius: BorderRadius.circular(10),
),
),
maxSuggestionsInViewPort: 4,
itemHeight: 50,
suggestionsDecoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
onTap: (value) {
setState(() {
_selectedSem = value;
});
if (kDebugMode) {
print(value);
}
},
suggestions: const [
'Afghanistan',
'Turkey',
'Germany',
'France',
'Italy',
],
),
),
],
),
),
Container(
height: 90,
padding: const EdgeInsets.only(right: 20, left: 20, bottom: 20),
decoration: const BoxDecoration(
color: Colors.white,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_selectedYear == null
? const Text(
'Select a Year and a Semester to Continue',
style:
TextStyle(fontSize: 14, color: Colors.blueGrey),
)
: Text(_selectedYear + "->" + _selectedSem,
style: TextStyle(
fontSize: 16,
color: Colors.grey.shade800,
fontWeight: FontWeight.w600)),
MaterialButton(
onPressed: () {
CreateURL(_selectedYear, _selectedSem);
},
color: Colors.black,
minWidth: 50,
height: 50,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
padding: const EdgeInsets.all(0),
child: const Icon(
Icons.arrow_forward_ios,
color: Colors.blueGrey,
size: 24,
),
)
],
),
)
],
),
),
),
);
}
}
Ive tried placing the setstate in an 'if(mounted)' and that didn't work after looking at other similar questions.
i just changed the variables initialization and it worked.
String _selectedYear = "";
String _selectedSem = "";
and also added this logic to the setState
setState(() {
_selectedSem = value!;
});
this did the trick for me, try it out and see
I'm not sure but once you try this way. first, initialize value to a variable and then refresh state
_selectedYear = value!;
setState(() {});
or if you are using flutter version 2.5.3 or higher then you need to initialize variable or migrate to null safety.
I am have this app that uses a checkbox to receive inputs from users, for example select a type of storage you want (NVMe, ssd, hdd etc) i want a solution that if a checkbox or multiple checkboxes are selected, it outputs their values on the summary screen.I have tried youtube tutorials, i did not quite understand them. Here is my code thanks
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:signoff_app/Screens/preview.dart';
import 'package:signoff_app/storage/store.dart';
import 'package:signoff_app/widget/textformfields.dart';
class NewSign extends StatefulWidget {
NewSign({Key? key}) : super(key: key);
#override
State<NewSign> createState() => _NewSignState();
}
class _NewSignState extends State<NewSign> {
bool ssd = false;
bool hdd = false;
bool nvme = false;
bool m2 = false;
TextEditingController pcname = new TextEditingController();
TextEditingController motherboard = new TextEditingController();
TextEditingController casing = new TextEditingController();
TextEditingController ramSize = new TextEditingController();
TextEditingController ram = new TextEditingController();
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text(
'Sign Off a Computer',
style: GoogleFonts.lato(
fontSize: 16,
fontStyle: FontStyle.normal,
),
),
),
body: Container(
width: MediaQuery.of(context).size.width,
// color: Colors.black54,
child: Stack(
children: [
Container(
//margin: EdgeInsets.fromLTRB(24, 0, 0, 24),
padding: EdgeInsets.fromLTRB(32, 64, 32, 32),
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
// color: Colors.black54,
child: Column(
children: [
Expanded(
flex: 1,
child: SizedBox(
width: 100,
height: 100,
child: Image(
fit: BoxFit.contain,
image: AssetImage("./images/udlogo.png"),
),
),
),
Expanded(
flex: 3,
child: Column(
children: [
Row(
children: [
Expanded(
flex: 2,
child: TextFormField(
controller: pcname,
validator: (val) {
if (val!.isEmpty) {
return "required";
}
},
decoration: InputDecoration(
labelText: 'Pc Name',
// errorText: 'please enter pc name'
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6),
borderSide: BorderSide(
color: Colors.blue,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.grey,
width: 1.5,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.red,
width: 1.5,
),
),
),
),
),
SizedBox(
width: 24,
),
Expanded(
flex: 2,
child: TextFormField(
controller: motherboard,
decoration: InputDecoration(
labelText: 'MotherBoard',
// errorText: 'please enter pc name'
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6),
borderSide: BorderSide(
color: Colors.blue,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.grey,
width: 1.5,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.red,
width: 1.5,
),
),
),
),
),
],
),
SizedBox(
height: 62,
),
Row(
children: [
Expanded(
flex: 2,
child: TextFormField(
controller: ram,
validator: (val) {
if (val!.isEmpty) {
return "required";
}
},
decoration: InputDecoration(
labelText: 'Ram',
// errorText: 'please enter pc name'
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6),
borderSide: BorderSide(
color: Colors.blue,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.grey,
width: 1.5,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.red,
width: 1.5,
),
),
),
),
),
SizedBox(
width: 24,
),
Expanded(
flex: 2,
child: TextFormField(
controller: casing,
decoration: InputDecoration(
labelText: 'Casing',
// errorText: 'please enter pc name'
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6),
borderSide: BorderSide(
color: Colors.blue,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.grey,
width: 1.5,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.red,
width: 1.5,
),
),
),
),
),
],
),
SizedBox(height: 24),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Storage',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w900,
),
),
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
//ssd checkbox
Text("SSD"),
SizedBox(width: 2),
Checkbox(
value: ssd,
onChanged: (bool? value) {
setState(() {
ssd = value!;
});
},
),
//hdd checkbox
SizedBox(width: 16),
Text("HDD"),
SizedBox(width: 2),
Checkbox(
value: hdd,
onChanged: (bool? value) {
setState(() {
hdd = value!;
});
},
),
SizedBox(width: 16),
//Nvme checkbox
Text("NVMe"),
SizedBox(width: 2),
Checkbox(
value: nvme,
onChanged: (bool? value) {
setState(() {
ssd = value!;
});
},
),
//m.2 checkbox
SizedBox(width: 16),
Text("M.2"),
SizedBox(width: 2),
Checkbox(
value: m2,
onChanged: (bool? value) {
setState(() {
m2 = value!;
});
},
),
],
),
],
),
],
),
),
Expanded(
flex: 1,
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: 45,
child: ElevatedButton(
style:
ElevatedButton.styleFrom(primary: Colors.red),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => PreviewSel(pcname.text,
motherboard.text, ram.text, casing.text),
),
);
},
child: Text('Submit'),
),
),
),
),
],
),
),
],
),
),
),
);
}
}
It seems to me that you have everything to now create your Text component. You update the booleans using setState in such a way that tapping the checkbox will update the state value, allowing you to use these variables inside a Widget, which will update when one of the values changes.
final String _summary = 'ssd: $ssd, hdd: $hdd, nvme: $nvme m2: $m2';
print(_summary); // 'ssd: false, hdd: false, nvme: false, m2: false';
...
Text(_summary);
The searcher bar is not working, where did i get an error?
I get this error in the terminal when I added expanded:
RenderFlex children have non-zero flex but incoming height constraints are unbounded.
I would like the hints from lost when searching to appear.Is everything logically arranged? I am new in flutter and not everything is clear to me.
Widget _profilePage(BuildContext context) {
(context, state) {
return SafeArea(
child: Align(
alignment: const Alignment(0, -1 / 1.6),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_buildSearchBar(),
],
),
),
),
);
}
List<String> newAllBreed = List.from(allBreed);
static List<String> allBreed =
["Affenpinscher",
"Afghan Hound",
"Aidi",
"Airedale Terrier",
"Akbash Dog",
"Akita"];
void search(String value) {
setState(() {
newAllBreed = allBreed
.where((string) =>
string.toLowerCase().contains(value.toLowerCase()))
.toList();
});
}
Widget _buildSearchBar() {
return Column(children: [
ConstrainedBox(
constraints: const BoxConstraints.tightFor(width: 350),
child: TextFormField(
controller: controller,
onFieldSubmitted: search,
decoration: InputDecoration(
labelText: 'Search',
hintText: 'Search',
fillColor: Colors.white,
filled: true,
isDense: true,
suffixIcon: GestureDetector(
onTap: () {
controller.clear();
},
child: const Padding(
padding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
child: Icon(
Icons.clear,
size: 30,
),
),
),
prefixIcon: GestureDetector(
onTap: () {
search(controller.text);
},
/// widget isntead of normal button
// cancellationWidget: Text("Cancel"),
child: const Padding(
padding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
child: Icon(
Icons.search_outlined,
size: 30,
),
),
),
focusedBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(30),
),
borderSide: BorderSide(
width: 2,
color: Colors.teal,
),
),
disabledBorder: InputBorder.none,
border: InputBorder.none,
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(30),
),
borderSide: BorderSide(
width: 2,
color: Colors.grey,
),
),
errorBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(5),
),
borderSide: BorderSide(
width: 2,
color: Colors.red,
),
),
),
),
),
Expanded(
child: ListView(
padding: EdgeInsets.all(12.0),
children: newAllBreed.map((data) {
return ListTile(
title: Text(data),
onTap: ()=> print(data),);
}).toList(),
),
)
]);
}
Flutter is cool and you don't need to nest the Widgets unnecessarily. Since you are designing a typical search with list you can use Column widget instead of SingleChildScrollView. Simplified approach will be as below.
Column(children: [
TextFormField( .. ), // => Your search text box
Expanded(child: ListView( .. )) // => Search result
])
Full Snippet : For your understanding
Column(children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: controller,
onFieldSubmitted: search,
decoration: InputDecoration(
labelText: 'Search',
hintText: 'Search',
fillColor: Colors.white,
filled: true,
isDense: true,
suffixIcon: GestureDetector(
onTap: () {
controller.clear();
},
child: const Padding(
padding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
child: Icon(
Icons.clear,
size: 30,
),
),
),
prefixIcon: GestureDetector(
onTap: () {
search(controller.text);
},
/// widget isntead of normal button
// cancellationWidget: Text("Cancel"),
child: const Padding(
padding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
child: Icon(
Icons.search_outlined,
size: 30,
),
),
),
focusedBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(30),
),
borderSide: BorderSide(
width: 2,
color: Colors.teal,
),
),
disabledBorder: InputBorder.none,
border: InputBorder.none,
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(30),
),
borderSide: BorderSide(
width: 2,
color: Colors.grey,
),
),
errorBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(5),
),
borderSide: BorderSide(
width: 2,
color: Colors.red,
),
),
),
),
),
Expanded(
child: ListView(
padding: EdgeInsets.all(12.0),
semanticChildCount: newAllBreed.length,
children: newAllBreed.map((data) {
return ListTile(
title: Text(data),
onTap: () => print(data),);
}).toList(),
),
)
]);
I'm Working on app, and i'm navigating through pages using routes, i'm not using any hero or FloatingActionButtons but i'm getting this hero related error, does anybody has any idea what could be the cause of that?
Here's the navigation call
nextTapped()async{
if(occasionTitleTxtField.text.isEmpty || dateTxtField.text.isEmpty || detailsTxtField.text.isEmpty)
ErrorOverlay("Invalid Data", false);
else
{
await LoadingOverlay.of(context).during(UserOperations().createFirstOccasion(context, occasionTitleTxtField.text, dateTxtField.text, detailsTxtField.text, repeatEveryYear, timeLimit)).then((value){
if(value.elementAt(0) == "true")
Navigator.of(context).pushReplacementNamed('/firstGift',arguments: FirstGiftPage(value.elementAt(1),occasionTitleTxtField.text));
});
}
}
Here's the route_generator
class RouteGenerator {
static Route<dynamic> generateRoute(RouteSettings settings) {
// Getting arguments passed in while calling Navigator.pushNamed
final args = settings.arguments;
switch (settings.name) {
case '/':
return MaterialPageRoute(builder: (_) => SplashScreen());
case '/login':
return MaterialPageRoute(builder: (_) => LoginPage());
case '/homepage':
return MaterialPageRoute(builder: (_) => HomePage());
case '/signUp':
return MaterialPageRoute(builder: (_) => SignUpScreen());
case '/otpScreen':
return MaterialPageRoute(builder: (_) {
OTPScreen screenArgs = args;
return OTPScreen(screenArgs.phoneNumber,screenArgs.countryCode);
});
case '/phoneNumber':
return MaterialPageRoute(builder: (_) {
PhoneNumberScreen screenArgs = args;
return PhoneNumberScreen(screenArgs.Provider);
});
case '/interests':
return MaterialPageRoute(builder: (_) => InterestsPage());
case '/invitation':
return MaterialPageRoute(builder: (_) => InvitationPage());
case '/firstOccasion':
return MaterialPageRoute(builder: (_) => FirstOccasion());
case '/firstGift':
return MaterialPageRoute(builder: (_) {
FirstGiftPage screenArgs = args;
return FirstGiftPage(screenArgs.occasionID,screenArgs.occasionTitle);
});
case '/map':
return MaterialPageRoute(builder: (_) => MapsPage());
default:
return _errorRoute();
}
}
static Route<dynamic> _errorRoute() {
return MaterialPageRoute(builder: (_) {
return Scaffold(
appBar: AppBar(
title: Text('Error'),
),
body: Center(
child: Text('UnderConstruction'),
),
);
});
}
}
Page i want to navigate to
class FirstGiftPage extends StatefulWidget {
String occasionID;
String occasionTitle;
static LatLng storeLocation;
FirstGiftPage(this.occasionID,this.occasionTitle);
#override
_FirstGiftPageState createState() => _FirstGiftPageState();
}
class _FirstGiftPageState extends State<FirstGiftPage> {
TextEditingController giftTitleTxtField = TextEditingController();
TextEditingController giftLinkTxtField = TextEditingController();
TextEditingController giftPriceTxtField = TextEditingController();
TextEditingController giftStoreAddTxtField = TextEditingController();
int giftCounter = 0;
TextEditingController detailsTxtField = TextEditingController();
Future<File> imageFile;
nextTapped()async{
if(giftTitleTxtField.text.isEmpty || giftLinkTxtField.text.isEmpty || giftPriceTxtField.text.isEmpty || detailsTxtField.text.isEmpty)
ErrorOverlay("Invalid Data",false);
else
{
Map<String,dynamic> giftData={
"giftName" : giftTitleTxtField.text,
"giftLink" : giftLinkTxtField.text,
"giftPrice" : giftPriceTxtField.text,
"storeAddress": giftStoreAddTxtField.text,
"details" : detailsTxtField.text,
"giftQuantity" : giftCounter,
"images":[imageFile.toString()],
"occasionID": widget.occasionID
};
ErrorOverlay("Gift Done",true);
Navigator.of(context).pushReplacementNamed("/homepage");
}
}
showMaps(){
Navigator.of(context).pushNamed("/map");
}
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color.fromRGBO(246, 76, 77, 1),
Color.fromRGBO(156, 51, 117, 1)
],
begin: Alignment .topRight,
end: Alignment.bottomLeft
)
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar:AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.transparent,
elevation: 0,
bottom: PreferredSize(
preferredSize: Size(0.0, 80.0),
child: Padding(
//TODO::Change padding to ScreenWidth - 300 / 2
padding: const EdgeInsets.only(left: 55.0 ,right: 55.0,bottom: 30.0),
child: Text(AppLocalizations.of(context).firstGift,style: TextStyle(color: Colors.white,fontSize: 30.0),textAlign: TextAlign.center,maxLines: 2,),
),
),
),
body: Padding(
padding: const EdgeInsets.only(top: 20.0,left: 15.0,right: 15.0),
child: Align(
alignment: Alignment.topCenter,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: giftTitleTxtField,
obscureText: false,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding:EdgeInsets.only(top:20.0,bottom:20.0,left: 15.0),
hintText: AppLocalizations.of(context).giftName,
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1
),
borderRadius: BorderRadius.circular(30.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1
),
borderRadius: BorderRadius.circular(30.0),
),
prefix: Container(width: 10.0,),
hintStyle: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16,
)
),),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: giftLinkTxtField,
obscureText: false,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding:EdgeInsets.only(top:20.0,bottom:20.0,left: 15.0),
hintText: AppLocalizations.of(context).giftLink,
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1
),
borderRadius: BorderRadius.circular(30.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1
),
borderRadius: BorderRadius.circular(30.0),
),
prefix: Container(width: 10.0,),
hintStyle: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16,
)
),),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: giftPriceTxtField,
obscureText: false,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding:EdgeInsets.only(top:20.0,bottom:20.0,left: 15.0),
hintText: AppLocalizations.of(context).giftPrice,
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1
),
borderRadius: BorderRadius.circular(30.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1
),
borderRadius: BorderRadius.circular(30.0),
),
prefix: Container(width: 10.0,),
hintStyle: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16,
)
),),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
readOnly: true,
onTap: showMaps,
controller: giftStoreAddTxtField,
obscureText: false,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding:EdgeInsets.only(top:20.0,bottom:20.0,left: 15.0),
hintText: AppLocalizations.of(context).giftStoreAdd,
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1
),
borderRadius: BorderRadius.circular(30.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1
),
borderRadius: BorderRadius.circular(30.0),
),
hintStyle: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16,
)
),),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(AppLocalizations.of(context).giftQuantity,style: TextStyle(color: Colors.white),),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Counter(
initialValue: giftCounter,
minValue: 0,
maxValue: 10,
step: 1,
decimalPlaces: 0,
textStyle: TextStyle(color: Colors.white),
onChanged: (value) { // get the latest value from here
setState(() {
giftCounter = value;
});
},
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
enabled: false,
obscureText: false,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding: EdgeInsets.only(top: 20),
hintText: widget.occasionTitle,
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1
),
borderRadius: BorderRadius.circular(20.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1
),
borderRadius: BorderRadius.circular(20.0),
),
prefix: Container(width: 10.0,),
hintStyle: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16,
)
),),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
maxLines: null,
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.center,
controller: detailsTxtField,
obscureText: false,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding: EdgeInsets.only(top: 20),
hintText: AppLocalizations.of(context).details,
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1
),
borderRadius: BorderRadius.circular(20.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1
),
borderRadius: BorderRadius.circular(20.0),
),
prefix: Container(width: 10.0,),
hintStyle: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16,
height: 4.0
)
),),
),
InkWell(
onTap: null,
child: Align(
alignment: Alignment.centerRight,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 50.0,
height: 50.0,
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.white,width: 4.0),
borderRadius: BorderRadius.circular(2.0)
),
child: Center(
child: Icon(Icons.camera_alt_outlined,color: Colors.white,size: 25.0,),
),
),
),
),
)
],
),
),
),
bottomNavigationBar: BottomAppBar(
child: Container(
child: Wrap(
//mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Align(
alignment: MyApp.getLocale(context).languageCode == "ar" ? Alignment.centerLeft:Alignment.centerRight,
child: Text("(4/5)"),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: LinearProgressIndicator(
minHeight: 10.0,
backgroundColor: Colors.white,
value: 0.80,
valueColor: AlwaysStoppedAnimation<Color>(Colors.orange),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: (){
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (BuildContext context)=> FirstGiftPage("","")));
},
child: Text(AppLocalizations.of(context).ignore,style: TextStyle(decoration: TextDecoration.underline),)),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: nextTapped,
child: Container(
width: 80.0,
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
gradient: LinearGradient(
colors: [
Color.fromRGBO(246, 76, 77, 1),
Color.fromRGBO(156, 51, 117, 1)
],
begin: Alignment .topRight,
end: Alignment.bottomLeft
)
),
child: Center(child: Text(AppLocalizations.of(context).next, style: TextStyle(color: Colors.white),)),
),
),
)
],
)
],
),
),
),
),
);
}
}
Here's the error
════════ Exception caught by scheduler library ═════════════════════════════════════════════════════
The following assertion was thrown during a scheduler callback:
There are multiple heroes that share the same tag within a subtree.
Within each subtree for which heroes are to be animated (i.e. a PageRoute subtree), each Hero must have a >unique non-null tag.
In this case, multiple heroes had the following tag:
Here is the subtree for one of the offending heroes: Hero
tag:
state: _HeroState#48fb7
When the exception was thrown, this was the stack:
#0 Hero._allHeroesFor.inviteHero. >(package:flutter/src/widgets/heroes.dart:268:11)
#1 Hero._allHeroesFor.inviteHero (package:flutter/src/widgets/heroes.dart:279:8)
#2 Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:298:21)
#3 SingleChildRenderObjectElement.visitChildren >(package:flutter/src/widgets/framework.dart:6105:14)
#4 Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:311:15)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
If you are using more than one floating action button then you need to pass your own tag to each button like this
FloatingActionButton(
heroTag: "tag1",
)
FloatingActionButton(
heroTag: "tag2",
)
By default, the heroTag is tag so in this case, you will get an error.
Second thing
If you are using more than one hero animation widget on the same page and share the same tag then also same error exist so you need to pass your own tag to each Hero widget
I solved this by creating a new file for the page i want to navigate to and it worked, have no idea how
I am creating a Password Manager Application and when user entering his details then I wont to show them a slider which generates a password in upper Password field. I have created a some code but i am not getting result as expected when user click on GENERATE PASSWORD the it show the following output.
Expected output:-
Here is my code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class PasswordInput extends StatefulWidget {
#override
_PasswordInputState createState() => _PasswordInputState();
}
class _PasswordInputState extends State<PasswordInput> {
bool _obscureText = true;
int generatePasswordHelper = 0;
String _passwordStrength = "Hello";
int _currentRangeValues = 6;
void _toggle() {
setState(() {
_obscureText = !_obscureText;
});
}
Widget WebsiteName() {
return TextFormField(
textCapitalization: TextCapitalization.words,
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: "Name of website",
labelStyle: TextStyle(fontSize: 14, color: Colors.grey.shade400),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.grey.shade300,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.red,
),
),
),
);
}
Widget WebsiteAddress() {
return TextFormField(
keyboardType: TextInputType.url,
decoration: InputDecoration(
labelText: "Website address",
labelStyle: TextStyle(fontSize: 14, color: Colors.grey.shade400),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.grey.shade300,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.red,
),
),
),
);
}
Widget UserName() {
return TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: "Username / Email",
labelStyle: TextStyle(fontSize: 14, color: Colors.grey.shade400),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.grey.shade300,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.red,
),
),
),
);
}
Widget Password() {
return TextFormField(
keyboardType: TextInputType.text,
obscureText: _obscureText,
decoration: InputDecoration(
labelText: "Password",
labelStyle: TextStyle(fontSize: 14, color: Colors.grey.shade400),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.grey.shade300,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.red,
),
),
suffixIcon: IconButton(
icon: Icon(
_obscureText ? Icons.visibility : Icons.visibility_off,
color: Colors.grey.shade600,
),
onPressed: _toggle,
),
),
);
}
Widget Note() {
return TextFormField(
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.sentences,
maxLines: null,
decoration: InputDecoration(
labelText: "Note",
labelStyle: TextStyle(fontSize: 14, color: Colors.grey.shade400),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.grey.shade300,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.red,
),
),
),
);
}
Widget GeneratePassword() {
this.generatePasswordHelper = 0;
return Container(
padding: EdgeInsets.only(left: 10),
child: RichText(
text: TextSpan(
style: TextStyle(
color: Colors.deepOrange,
),
children: <TextSpan>[
TextSpan(
text: "GENERATE PASSWORD",
recognizer: TapGestureRecognizer()
..onTap = () {
setState(() {
generatePasswordHelper = 1;
});
})
]),
),
);
}
Widget PasswordGenerator() {
return Container(
color: Colors.grey.shade200,
//height: MediaQuery.of(context).size.width / 2,
width: MediaQuery.of(context).size.width / 1.1,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: EdgeInsets.only(left: 10),
child: Text(
_passwordStrength,
),
),
IconButton(
icon: Icon(Icons.close),
onPressed: () {
setState(() {
generatePasswordHelper = 0;
});
},
),
],
),
Slider(
value: _currentRangeValues.toDouble(),
min: 0,
max: 100,
divisions: 27,
onChanged: (double newValue) {
setState(() {
_currentRangeValues = newValue.round();
});
},
semanticFormatterCallback: (double newValue) {
return '${newValue.round()} dollars';
}
)
],
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
//resizeToAvoidBottomPadding: false,
appBar: AppBar(
centerTitle: true,
title: Text("Add Password"),
),
body: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(),
child: Container(
padding: EdgeInsets.only(left: 16, right: 16),
child: Column(
//mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 20,
),
WebsiteName(),
SizedBox(
height: 20,
),
WebsiteAddress(),
SizedBox(
height: 20,
),
UserName(),
SizedBox(
height: 20,
),
Password(),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (generatePasswordHelper == 0)
GeneratePassword()
else
PasswordGenerator()
],
),
SizedBox(
height: 20,
),
Note(),
SizedBox(
height: 20,
),
Container(
height: 50,
width: double.infinity,
child: FlatButton(
onPressed: () {},
padding: EdgeInsets.all(0),
child: Ink(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color(0xffff5f6d),
Color(0xffff5f6d),
Color(0xffffc371),
],
),
),
child: Container(
alignment: Alignment.center,
constraints: BoxConstraints(
maxWidth: double.infinity, minHeight: 50),
child: Text(
"Submit",
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
),
),
],
),
),
),
),
);
}
}
You should provide an initalValue to your password field. Init a variable with a default blank value, then when you generate a password save it in that variable and use it as the password field value
https://api.flutter.dev/flutter/widgets/FormField/initialValue.html
class _PasswordInputState extends State<PasswordInput> {
bool _obscureText = true;
int generatePasswordHelper = 0;
String _passwordStrength = "Hello";
int _currentRangeValues = 6;
String currentPassword = ""
...
Widget Password() {
return TextFormField(
keyboardType: TextInputType.text,
obscureText: _obscureText,
initialValue: currentPassword
...
When you generate a password save it in currentPassword using setState