Flutter double parsing error Invalid double - android

I'm having trouble with this code which is giving me this error.
I'm really new to flutter and this is my first project.
import 'dart:ffi';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: BmiCalculator(),
);
}
}
//create a statefull widget
class BmiCalculator extends StatefulWidget {
BmiCalculator({Key key}) : super(key: key);
#override
_BmiCalculatorState createState() => _BmiCalculatorState();
}
class _BmiCalculatorState extends State<BmiCalculator> {
int currentindex = 0;
double result = 0;
double height = 0;
double weight = 0;
TextEditingController heightController = TextEditingController();
TextEditingController weightController = TextEditingController();
#override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(
title: Text("BMI Calculator", style: TextStyle(color: Colors.black),),
elevation: 0.0,
backgroundColor: Color(0xfffafafa),
actions: [
IconButton(
onPressed: () {},
icon: Icon(
Icons.settings,
color: Colors.black,
)
)
],
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
radioButton("Man", Colors.blue, 0),
radioButton("Woman", Colors.pink, 1),
],
),
SizedBox(
height: 20.0 ,
),
Text(
"Your Height in CM" ,
style: TextStyle(
fontSize: 18.0,
),
),
SizedBox(
height: 8.0,
),
TextField(
keyboardType: TextInputType.number,
controller: heightController,
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: "Your Height In CM",
filled: true,
fillColor: Colors.grey[200],
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
),
),
SizedBox(
height:20.0,
),
Text(
"Your Weight in KG" ,
style: TextStyle(
fontSize: 18.0,
),
),
SizedBox(
height: 8.0,
),
TextField(
keyboardType: TextInputType.number,
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: "Your Weight In KG",
filled: true,
fillColor: Colors.grey[200],
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
),
),
SizedBox(height: 20.0,),
Container(
width: double.infinity,
height: 50.0,
child: FlatButton(
onPressed: () {
setState(() {
height = double.parse(heightController.value.text);
weight = double.parse(weightController.value.text);
});
calculateBmi(height, weight);
},
color: Colors.blue,
child:Text("Calculate", style: TextStyle(
color: Colors.white,
)),
),
),
SizedBox(
height: 20.0,
),
Container(
width: double.infinity,
child: Text(
"Your BMI is : ",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.bold,
)
)
),
SizedBox(
height: 50.0,
),
Container(
width: double.infinity,
child: Text(
"$result",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.bold,
)
)
),
],
),
),
)
),
);
}
void calculateBmi(double height, double weight){
double finalresult = weight / (height * height / 10000);
double bmi = finalresult;
setState(() {
result = bmi;
});
}
void changeIndex(int index){
setState(() {
currentindex = index;
});
}
Widget radioButton(String value, Color color, int index){
return Expanded(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 12.0),
height: 80.0,
child: FlatButton(
color: currentindex == index ? color : Colors.grey[200],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
onPressed: () {
changeIndex(index);
},
child: Text(value, style: TextStyle(
color: currentindex == index ? Colors.white : color,
fontSize: 22.0,
fontWeight: FontWeight.bold,
)),
)
),
);
}
}
and this is the error:
════════ Exception caught by gesture ═══════════════════════════════════════════════════════════════
The following FormatException was thrown while handling a gesture:
Invalid double
When the exception was thrown, this was the stack:
#0 double.parse (dart:core-patch/double_patch.dart:111:28)
#1 _BmiCalculatorState.build.. (package:lab1_flutter/main.dart:129:41)
#2 State.setState (package:flutter/src/widgets/framework.dart:1244:30)
#3 _BmiCalculatorState.build. (package:lab1_flutter/main.dart:127:23)
#4 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:993:19)
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#50a78
debugOwner: GestureDetector
state: possible
won arena
finalPosition: Offset(150.6, 444.6)
finalLocalPosition: Offset(138.6, 36.6)
button: 1
sent tap down
════════════════════════════════════════════════════════════════════════════════════════════════════

What is happening on line 129 ?
Can you tell us what is displayed by changing this code ?
setState(() {
print(heightController.value.text);
print(weightController.value.text);
height = double.parse(heightController.value.text);
weight = double.parse(weightController.value.text);
});
My guess is that you use heightController in the TextField, but not weightController, so its value is null, so it throw an error when you parse it.

Related

How to resize TextField() text to fit the max width of an Expanded() widget

i want to resize the text of a TextField() widget in order to fit the max width of its Expanded() parent, this width is determined by flex: 10 as you can see in the code.
However, i do not know how can i achieve this result. I also tried the AutoSizeTextField() package with no success. Maybe someone can figure out how to do this.
Thank you in advance.
Edit. If it is not clear, the text is entered by the user. I want to resize it dynamically. The following image is just an example of the current behaviour of the App when user enters "This text should be resized".
Edit. I updated the code so that is clear what i am trying to do.
I have a list of transactions. When the user click on a transaction a dialog will popup in order to let the user edit the info he has provided.
This is the code which call the dialog, the dialog is ModificaTransazione().
Material(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: InkWell(
borderRadius: BorderRadius.circular(10),
onTap: () {
//sleep(Duration(milliseconds: 800));
showDialog(
context: context,
builder: (context) {
return Dialog(
insetPadding: EdgeInsets.only(
bottom: 0.0), //QUESTO TOGLIE SPAZIO DALLA TASTIERA
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40)),
elevation: 16,
child: ModificaTransazione(
idtransazione: tx.id,
titolotransazione: tx.titolo,
importotransazione: tx.costo,
datatransazione: tx.data,
indicetransazione: tx.indicecategoria,
notatransazione: tx.nota,
listatransazioni: widget.transactions,
eliminatransazione: widget.deleteTx,
listanomicategorie: widget.listanomicategorie,
refreshSezioneFinanziaria:
widget.refreshFinanceScreen,
size: size),
);
},
).then((_) {
setState(() {});
});
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: SizedBox(
height: size.height * 0.10,
// color: Colors.red,
child: Row(
children: [
Expanded(
flex: 4,
child: Container(
margin: const EdgeInsets.only(left: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
FittedBox(
child: Text(
tx.titolo,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
FittedBox(
child: Text(
DateFormat('dd MMMM, yyyy', 'it')
.format(tx.data),
style: const TextStyle(
color: Colors.grey,
),
),
),
],
),
),
),
Expanded(
flex: 5,
child: Container(
alignment: Alignment.centerRight,
margin: const EdgeInsets.symmetric(horizontal: 15),
child: FittedBox(
child: Text(
'- ${ciframostrata(tx.costo)} €',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Color(0xFF7465fc)),
),
),
),
),
],
),
),
),
),
),
This is "ModificaTransazione()" literally "Edit Transaction" in Italian.
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_application_1/models/transaction.dart';
import 'package:flutter_application_1/widget/transactions_list.dart';
import 'package:intl/intl.dart';
import 'package:auto_size_text_field/auto_size_text_field.dart';
class ModificaTransazione extends StatefulWidget {
ModificaTransazione({
Key? key,
required this.size,
required this.idtransazione,
required this.titolotransazione,
required this.importotransazione,
required this.datatransazione,
required this.indicetransazione,
required this.notatransazione,
required this.listatransazioni,
required this.eliminatransazione,
required this.listanomicategorie,
required this.refreshSezioneFinanziaria,
}) : super(key: key);
final Size size;
final String idtransazione;
String titolotransazione;
double importotransazione;
DateTime datatransazione;
int indicetransazione;
String notatransazione;
List<String> listanomicategorie;
List<Transaction> listatransazioni;
final Function eliminatransazione;
final Function refreshSezioneFinanziaria;
#override
State<ModificaTransazione> createState() => _ModificaTransazioneState();
}
class _ModificaTransazioneState extends State<ModificaTransazione> {
var _notaController = TextEditingController();
var _importoController = TextEditingController();
var _titoloController = TextEditingController();
#override
void initState() {
super.initState();
if (widget.notatransazione != "") {
_notaController = TextEditingController(text: widget.notatransazione);
} else {
_notaController = TextEditingController(text: "Aggiungi");
}
_importoController = TextEditingController(
text: "${ciframostrata(widget.importotransazione)}");
_titoloController = TextEditingController(text: widget.titolotransazione);
}
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
width: widget.size.width * 0.8,
height: widget.size.height * 0.60,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding:
const EdgeInsets.only(top: 30, left: 30, right: 30, bottom: 30),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
GestureDetector(
onTap: () {
setState(() {
Navigator.of(context).pop();
});
},
child: Icon(
Icons.cancel,
color: Colors.black,
),
),
Spacer(),
Expanded(
//
// THIS IS WHAT I WANT TO RESIZE, BUT FITTEDBOX IS CAUSING RENDERBOX IS NOT LAID OUT
//
flex: 10,
child: FittedBox(
fit: BoxFit.fitWidth,
child: TextField(
maxLines: 1,
decoration: InputDecoration(
border: InputBorder.none,
),
controller: _titoloController,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
onSubmitted: (_) => salvaModifica(),
),
),
),
Spacer(),
GestureDetector(
child: Icon(
Icons.delete_outline_rounded,
color: Colors.black,
),
onTap: () {
print("Transazione Eliminata");
widget.eliminatransazione(widget.idtransazione);
Navigator.of(context).pop();
}),
],
),
Container(
padding: EdgeInsets.all(15),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Theme.of(context).primaryColor.withOpacity(0.1),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Flexible(
flex: 4,
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
),
controller: _importoController,
keyboardType: const TextInputType.numberWithOptions(
decimal: true),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 60,
color: Theme.of(context).primaryColor,
),
onSubmitted: (_) => salvaModifica(),
),
),
Flexible(
//color: Colors.red,
//alignment: Alignment.centerRight,
//width: widget.size.width * 0.10,
// color: Colors.red,
child: Text(
"€",
style: TextStyle(
fontSize: 40,
color:
Theme.of(context).primaryColor.withOpacity(0.8),
),
),
),
],
),
),
// AutoSizeText(
// "${ciframostrata(widget.importotransazione)} €",
// maxLines: 1,
// style: TextStyle(
// fontSize: 70,
// color: Theme.of(context).primaryColor,
// ),
// ),
// ),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Categoria",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Colors.grey,
),
),
Container(
child: Row(
children: [
GestureDetector(
child: Text(
"${funzioneCategoria(indicenuovo ?? widget.indicetransazione, widget.listanomicategorie)[2]} ",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: funzioneCategoria(
indicenuovo ?? widget.indicetransazione,
widget.listanomicategorie)[1]),
),
onTap: _askedToLead,
),
Icon(
funzioneCategoria(
indicenuovo ?? widget.indicetransazione,
widget.listanomicategorie)[0],
color: funzioneCategoria(
indicenuovo ?? widget.indicetransazione,
widget.listanomicategorie)[1]),
],
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Data",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Colors.grey,
),
),
InkWell(
// borderRadius: BorderRadius.circular(10),
onTap: _presentDatePicker,
child: Text(
DateFormat('dd MMMM, yyyy', 'it')
.format(_selectedDate ?? widget.datatransazione),
style: TextStyle(
color: Colors.black, //Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
),
),
),
],
),
Container(
//color: Colors.red,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
"Nota",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Colors.grey,
),
),
),
Expanded(
child: (_notaController.text != "Aggiungi")
? TextField(
textAlign: TextAlign.end,
decoration: InputDecoration(
border: InputBorder.none,
),
controller: _notaController,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
),
onSubmitted: (_) => salvaModifica(),
)
: TextField(
textAlign: TextAlign.end,
decoration: InputDecoration(
border: InputBorder.none,
),
controller: _notaController,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey[600],
),
onSubmitted: (_) => salvaModifica(),
)),
],
),
),
modificato == true
? TextButton(
child: Text("Salva"),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Theme.of(context).primaryColor),
foregroundColor:
MaterialStateProperty.all(Colors.white),
),
onPressed: () {
premuto = true;
salvaModifica();
},
)
: SizedBox(),
],
),
),
),
);
}
You can use the FittedBox widget to dynamically change text size based on width or height.
FittedBox(
fit: BoxFit.fitWidth,
child: TextField(
maxLines: 1,
decoration: InputDecoration(
border: InputBorder.none,
),
controller: _titoloController,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
onSubmitted: (_) => salvaModifica(),
)),
The text will be resized based on the width of Expanded.
I have checked your code. You can do the following:
Row(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: () {
setState(() {
Navigator.of(context).pop();
});
},
child: Icon(
Icons.cancel,
color: Colors.black,
),
),
Expanded(
child: TextField(
maxLines: 4,
decoration: InputDecoration(
border: InputBorder.none,
),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
GestureDetector(
child: Icon(
Icons.delete_outline_rounded,
color: Colors.black,
),
onTap: () {
print("Transazione Eliminata");
Navigator.of(context).pop();
}),
],
),

RadioListTile Flutter in loop

I have a problem with RadioListTile it doesn't work
Im trying to create a list of RadioListTile to fill in with my data from firebase using for loop. When I click it it do receive the action, but I cannot check the box when click on it.
I have been trying to solve it for days. Anyone can help?
This is my code:
import 'package:eatwell/src/helpers/changescreen.dart';
import 'package:eatwell/src/model/itemmodel.dart';
import 'package:eatwell/src/model/platemodel.dart';
import 'package:eatwell/src/pages/cartPage.dart';
import 'package:eatwell/src/provider/customplate.dart';
import 'package:eatwell/src/provider/item.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class CustomDetail extends StatefulWidget {
final CustomModel custom;
const CustomDetail({Key key, this.custom}) : super(key: key);
#override
_CustomDetail createState() => _CustomDetail();
}
class _CustomDetail extends State<CustomDetail> {
#override
Widget build(BuildContext context) {
final carbsProvider = Provider.of<CarbsProvider>(context);
var mycarb = 1;
return Scaffold(
appBar: AppBar(
title: Text(
"Preset Meal",
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.black,
fontFamily: 'DancingScript',
),
),
centerTitle: true,
actions: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 8.0, right: 8.0),
child: Stack(
children: <Widget>[
IconButton(
icon: Icon(
Icons.shopping_bag_outlined,
size: 40,
),
onPressed: () {
changeScreen(context, Cart());
}),
Positioned(
right: 3,
bottom: 0,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(2, 3),
blurRadius: 3)
]),
child: Padding(
padding: const EdgeInsets.only(left: 4, right: 4),
child: Text(
"2",
style: TextStyle(
color: Colors.red,
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
),
),
)
],
),
)
],
),
body: SafeArea(
child: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20, bottom: 10, top: 30),
child: Container(
decoration: BoxDecoration(
color: Colors.cyanAccent,
borderRadius: BorderRadius.circular(100),
),
height: 300,
alignment: Alignment.center,
child: Image(
image: NetworkImage(widget.custom.image),
height: 300,
width: 300,
),
),
),
Text(
widget.custom.name,
style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
Text(
("RM ${widget.custom.price}"),
style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
for (var i = 0; i < widget.custom.carbnum; i++)
Column(
children: <Widget>[
ListTile(
title: Text("Choose Your Carbohydrates"),
),
for (var i = 0; i < carbsProvider.carbs.length; i++)
RadioListTile(
title: Text(carbsProvider.carbs[i].name),
value: i,
onChanged: (var v) {
print("object");
mycarb = v;
},
groupValue: mycarb,
)
],
),
// for (var i = 0; i < widget.custom.fooditems.length; i++)
// Text(
// widget.custom.fooditems[i],
// style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold),
// )
],
),
));
}
}
Wrap your onChanged in setState.
just like
onChanged: (var v) {
setState((){
print("object");
mycarb = v;
});
},
According to the docs:
Calling setState notifies the framework that the internal state of this object has changed in a way that might impact the user interface in this subtree, which causes the framework to schedule a build for this State object.
Use setState method in onChanged method of RadioListTile widget and as answered by Abdul Qadir.

qrScanner inside Expanded layer, How to add two button in Flutter

In flutter, I want to make an application that scans qr code and display the qr text.
I have two buttons, which are done, scan again.
And how to put that 2 button, bottom of that scan area. If i try to put that button inside expanded layer, it looks all red
Here is the code & screenshot.
How can i solve this ?
import 'package:flutter/material.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:qr_code_scanner/qr_scanner_overlay_shape.dart';
void main() => runApp(MaterialApp(home: QRSCAN()));
const flash_on = "FLASH ON";
const flash_off = "FLASH OFF";
const front_camera = "FRONT CAMERA";
const back_camera = "BACK CAMERA";
class QRSCAN extends StatefulWidget {
const QRSCAN({
Key key,
}) : super(key: key);
#override
State<StatefulWidget> createState() => _QRSCANState();
}
class _QRSCANState extends State<QRSCAN> {
bool Done_Button = false;
var qrText = "";
QRViewController controller;
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.blueAccent),
onPressed: () {
Navigator.pop(context);
controller?.pauseCamera();
},
),
elevation: 0.0,
backgroundColor: Colors.white,
actions: <Widget>[
IconButton(
icon: Icon(Icons.help_outline, color: Colors.grey,),
onPressed: () {},
),
],
),
body: Column(
children: <Widget>[
Expanded(
child: QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.blueAccent,
borderRadius: 10,
borderLength: 130,
borderWidth: 5,
overlayColor: Color(0xff010040),
),
),
flex: 4,
),
Expanded(
child: FittedBox(
fit: BoxFit.contain,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text("$qrText", style: TextStyle(color: Colors.black,),),
InkWell(
onTap: () async {
Navigator.pop(context);
},
child: Container(
width: 100.0,
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(colors: [
Color(0xFF1E75BB),
Color(0xFF1EEABB),
])),
child: Center(
child: Text(
'Done',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontFamily: 'Play',
),
),
),
),
),
SizedBox(
height: 25,
),
InkWell(
onTap: () async {
setState(() {
qrText = "";
controller?.resumeCamera();
Done_Button = false;
});
},
child: Container(
width: 100.0,
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(colors: [
Color(0xFF1E75BB),
Color(0xFF1EEABB),
])),
child: Center(
child: Text(
'Again',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontFamily: 'Play',
),
),
),
),
),
],
),
),
flex: 1,
),
],
),
);
}
_isFlashOn(String current) {
return flash_on == current;
}
_isBackCamera(String current) {
return back_camera == current;
}
void _onQRViewCreated(QRViewController controller) {
this.controller = controller;
controller.scannedDataStream.listen((scanData) {
setState(() {
qrText = scanData;
controller?.pauseCamera();
Done_Button = true;
});
});
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
}
you can refactor your code as follows
` Column(children: <Widget>[
/* QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.blueAccent,
borderRadius: 10,
borderLength: 130,
borderWidth: 5,
overlayColor: Color(0xff010040),
),
),*/
SizedBox(height:5),
Center(
child: Container(height: 100, color: Colors.white, width: 100),
),
Text(
"$qrText",
style: TextStyle(
color: Colors.black,
),
),
InkWell(
onTap: () async {
Navigator.pop(context);
},
child: Container(
width: 100.0,
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(colors: [
Color(0xFF1E75BB),
Color(0xFF1EEABB),
])),
child: Center(
child: Text(
'Done',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontFamily: 'Play',
),
),
),
),
),
SizedBox(
height: 25,
),
InkWell(
onTap: () async {
setState(() {
qrText = "";
// controller?.resumeCamera();
// Done_Button = false;
});
},
child: Container(
width: 100.0,
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(colors: [
Color(0xFF1E75BB),
Color(0xFF1EEABB),
])),
child: Center(
child: Text(
'Again',
style: TextStyle(
color: Colors.white,
letterSpacing: 1.5,
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontFamily: 'Play',
),
),
),
),
),
]),
);`

Flutter not updating its animated text widget (Animated_Text_kit)

So this is the main code where I fetch the data from json and update my UI.
I have placed" //Area of Interest " comments where the code related to the problem lies.
class MainScreen extends StatefulWidget {
final curLocdata;
MainScreen({this.curLocdata});
#override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
Weather weather = Weather();
var cityName;
int temp;
int temp_min;
int temp_max;
Icon weatherIcon;
//Area of Interest 1
RotateAnimatedTextKit textSum;//created a widget of RotateAnimatedTextKit library.
String st;
//Area of Interest 2
#override
void initState() {
// TODO: implement initState
super.initState();
updateUI(widget.curLocdata);//calling update function to rebuild my UI state with new data
}
void updateUI(data) {
setState(() {
if (data == null) {
temp = 0;
cityName = 'Error';
weatherIcon = Icon(Icons.error);
return;
}
cityName = data['name'];
temp = data['main']['temp'].toInt();
temp_min = data['main']['temp_min'].toInt();
temp_max = data['main']['temp_max'].toInt();
var condition = data['weather'][0]['id'];
weatherIcon = weather.getIcon(condition);
textSum = weather.getMessage(temp);//Area of Interest 3
st = weather.subtext(condition);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SafeArea(
child: Column(
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
FlatButton(
onPressed: () async {
updateUI(await Network().getData());
},
child: Icon(
FontAwesomeIcons.locationArrow,
),
),
SizedBox(
width: 180.0,
child: TextLiquidFill(
waveDuration: Duration(seconds: 3),
loadDuration: Duration(seconds: 10),
text: 'OpenWeather',
waveColor: Colors.red,
boxBackgroundColor: Color(0xFF1B1B1D),
textStyle: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
fontFamily: 'Source Sans Pro',
),
boxHeight: 50.0,
),
),
FlatButton(
onPressed: () async {
String SName = await Navigator.push(context,
MaterialPageRoute(builder: (context) {
return Search();
}));
if (SName != null) {
updateUI(await Network().getDataName(
SName));
}
},
child: Icon(
Icons.add,
color: Colors.white,
size: 40,
),
),
],
),
),
Padding(
padding: EdgeInsets.fromLTRB(50, 50, 50, 0),
child: Row(
children: <Widget>[
SizedBox(
// margin: EdgeInsets.fromLTRB(0, 50, 260, 0),
child: TypewriterAnimatedTextKit(
totalRepeatCount: 200,
isRepeatingAnimation: true,
speed: Duration(milliseconds: 700),
text: [cityName,],
textAlign: TextAlign.left,
textStyle: TextStyle(
fontSize: 20,
fontFamily: 'Source Sans Pro',
),
),
),
],
)),
Expanded(
flex: 9,
child: Container(
margin: EdgeInsets.fromLTRB(50, 30, 50, 80),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
//mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.only(left: 20),
child: Text(
'$temp°',
style: TextStyle(
fontSize: 80,
fontWeight: FontWeight.bold,
fontFamily: 'Source Sans Pro',
),
),
),
),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.only(left: 20),
child: Text(
st,
style: TextStyle(
fontSize: 30,
fontFamily: 'Source Sans Pro',
color: Colors.grey[500]),
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 50),
child: Container(
child: textSum,//Used this textSum to show my animated text. problem
Area of Interest 4
),
),
Expanded(
child: SizedBox(
//width: double.infinity,
//height: 100,
child: Divider(
color: Colors.red,
),
),
),
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 38),
child: Text(
'$temp_min° - $temp_max°',
style: TextStyle(
fontSize: 20,
color: Colors.grey[500],
fontFamily: 'Source Sans Pro',
),
),
),
),
Expanded(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 20),
//padding: const EdgeInsets.all(8.0),
child: AvatarGlow(
endRadius: 30.0, //required
child: Material(
//required
elevation: 0.0,
shape: CircleBorder(),
child: CircleAvatar(
//backgroundColor: Colors.grey[100],
child: weatherIcon
// radius: 40.0,
//shape: BoxShape.circle
),
),
),
),
)
],
)`enter code here`
],
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Color(0xFF0C0C0C),
),
),
),
Now the weather.dart file from where I am returning RotateAnimatedTextKit widget depending upon the condition
class Weather{
//This return RotateAnimatedTextKit which is then held by textSum and is put as a child inside a container in MainScreen
RotateAnimatedTextKit getMessage(int temp) {
if (temp > 25) {
return RotateAnimatedTextKit(
isRepeatingAnimation: true,
totalRepeatCount: 200,
transitionHeight: 40,
text: ['It\'s 🍦','time and','drink plenty','of water'],
textStyle: TextStyle(fontSize: 30.0, fontFamily: "Source Sans Pro", color: Colors.red),
textAlign: TextAlign.start,
alignment: AlignmentDirectional.topStart // or Alignment.topLeft
);
} else if (temp > 20) {
return RotateAnimatedTextKit(
isRepeatingAnimation: true,
totalRepeatCount: 200,
transitionHeight: 50,
text: ['Time for','shorts','👕','but keep','some warm','clothes handy'],
textStyle: TextStyle(fontSize: 30.0, fontFamily: "Source Sans Pro", color: Colors.red),
textAlign: TextAlign.start,
alignment: AlignmentDirectional.bottomStart// or Alignment.topLeft
);
} else if (temp < 10) {
return RotateAnimatedTextKit(
isRepeatingAnimation: true,
totalRepeatCount: 200,
transitionHeight: 50,
text: ['You\'ll need','a 🧣','and','a 🧤','and a hot', 'soup and turkey'],
textStyle: TextStyle(fontSize: 30.0, fontFamily: "Source Sans Pro", color: Colors.red),
textAlign: TextAlign.start,
alignment: AlignmentDirectional.bottomStart // or Alignment.topLeft
);
} else {
return RotateAnimatedTextKit(
isRepeatingAnimation: true,
transitionHeight: 50,
totalRepeatCount: 200,
text: ['Bring a','🧥','just in case','and also avoid', 'cold breeze','and cold drinks'],
textStyle: TextStyle(fontSize: 30.0, fontFamily: "Source Sans Pro", color: Colors.red),
textAlign: TextAlign.start,
alignment: AlignmentDirectional.bottomStart // or Alignment.topLeft
);
}
}
The thing is that the UI doesn't get updated even when the conditions are different. So any Solutions to why the widget tree is not updating? But it runs only the default text. Also, the cityName which is under the TextLiquidFill doesn't get updated.
Short answer:
Use Keys
Example:
import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:flutter/material.dart';
class MyAnimatedText extends StatefulWidget {
const MyAnimatedText({Key? key}) : super(key: key);
#override
State<MyAnimatedText> createState() => _MyAnimatedTextState();
}
class _MyAnimatedTextState extends State<MyAnimatedText> {
bool isDarkMode = true;
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: isDarkMode ? Colors.grey[850] : Colors.amber[300]),
child: Column(
children: [
Container(
alignment: Alignment.topRight,
child: IconButton(
onPressed: () {
setState(() {
isDarkMode = !isDarkMode;
});
},
icon: Icon(isDarkMode ? Icons.light_mode : Icons.dark_mode))),
Padding(
padding: const EdgeInsets.all(15.0),
child: AnimatedTextKit(
key: ValueKey<bool>(isDarkMode),
animatedTexts: [
TypewriterAnimatedText(
isDarkMode ? 'Have a nice evening ;)' : 'Have a nice day :)',
cursor: isDarkMode ?'>':'<',
textStyle: TextStyle(
fontSize: 38,
color: isDarkMode ? Colors.amber[300] : Colors.grey[850]),
speed: const Duration(milliseconds: 100),
),
],
),
),
],
),
);
}
}
Result:
Background Information
I faced the same problem, when I tried to implement a dark / light change. The background color was defined in an other widget and changed, the font color was defined in the TypewriterAnimatedText Widget and only changed in the second loop. The color was not changing in the runnig animation.
Solution: use Keys
The Animation does not change beacause Flutter tries to keep the state of an StatefulWidget and the AnimatedTextKit is a Stateful Widget.
To force a rebuild you can use a Key.
a nice article can be found here: How to force a Widget to redraw in Flutter?
You can use WidgetsBinding.instance.addPostFrameCallback
For detail, you can reference https://www.didierboelens.com/faq/week2/
code snippet
#override
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_){
updateUI(widget.curLocdata);
});
}

Animating a container as soon as it is added to a widget list (as it appears )

how to animate the added containers as soon as they appear ? ( animation of height going from 0 to containerHeight)
here is a code to illustrate my question:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: Home(),
));
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
List<Widget> widgetList = [Container()];
class _HomeState extends State<Home> {
TextEditingController controller = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Animated container'),
backgroundColor: Colors.blue,
),
body: Container(
alignment: Alignment.topCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Center(
child: Padding(
//shift to left
padding: const EdgeInsets.only(left: 55.0),
child: Row(
children: widgetList.toList(),
),
),
),
],
),
),
FlatButton(
child: Text(
'Add',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setState(() {
add(controller.text);
});
},
color: Colors.blue,
),
FlatButton(
child: Text(
'Clear',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setState(() {
widgetList.clear();
});
},
color: Colors.blue,
),
TextField(
onChanged: (text) {},
textAlign: TextAlign.center,
controller: controller,
keyboardType: TextInputType.number,
style: TextStyle(
color: Colors.white,
fontSize: 25.0,
fontWeight: FontWeight.w300),
decoration: InputDecoration(
hintStyle: TextStyle(
color: Colors.white, fontWeight: FontWeight.w300),
fillColor: Colors.blue,
filled: true,
),
),
]),
),
);
}
}
void add(String containerHeight) {
widgetList.add(Padding(
padding: const EdgeInsets.all(3.0),
child: AnimatedContainer(
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(2.0),
),
duration: Duration(milliseconds: 165),
alignment: Alignment.center,
//color: Colors.red,
height: double.parse(containerHeight),
width: 29.0,
child: Text(
containerHeight,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: containerHeight.length == 1
? 19.0
: containerHeight.length == 2
? 19.0
: containerHeight.length == 3
? 16.0
: containerHeight.length == 4 ? 14.0 : 10.0),
),
)));
}
Screenshot of the ui
You just have to put the height of the container in the text field and press 'add', then the containers will appear directly without animation,
so my question is how to animate so that the height goes from 0 to containerHeight ?
i know it works when the widget is already there and we modify it's height, but i couldn't figure out how to do in that scenario ( adding to a list and displaying it directly ).
thank you.
Try the following code. It is working.
import 'package:flutter/material.dart';
import 'dart:async';
void main() {
runApp(MaterialApp(
home: Home(),
));
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
List<Widget> widgetList = [Container()];
StreamController<String> animationStream = StreamController();
class _HomeState extends State<Home> {
TextEditingController controller = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Animated container'),
backgroundColor: Colors.blue,
),
body: Container(
alignment: Alignment.topCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Center(
child: Padding(
//shift to left
padding: const EdgeInsets.only(left: 55.0),
child: Row(
children: widgetList.toList(),
),
),
),
],
),
),
FlatButton(
child: Text(
'Add',
style: TextStyle(color: Colors.white),
),
onPressed: () {
animationStream = StreamController();
setState(() {
add("0");
animationStream.sink.add(controller.text);
});
},
color: Colors.blue,
),
FlatButton(
child: Text(
'Clear',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setState(() {
widgetList.clear();
});
},
color: Colors.blue,
),
TextField(
onChanged: (text) {},
textAlign: TextAlign.center,
controller: controller,
keyboardType: TextInputType.number,
style: TextStyle(
color: Colors.white,
fontSize: 25.0,
fontWeight: FontWeight.w300),
decoration: InputDecoration(
hintStyle: TextStyle(
color: Colors.white, fontWeight: FontWeight.w300),
fillColor: Colors.blue,
filled: true,
),
),
]),
),
);
}
}
void add(String containerHeight) {
widgetList.add(new MyWidget());
}
class MyWidget extends StatelessWidget {
const MyWidget({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: animationStream.stream,
builder: (context, snapshot) {
String _hight = "0";
if (snapshot.hasData ) {
_hight = snapshot.data;
try { double.parse(_hight);} catch (e) { print('please enter a valid hight');_hight="0"; }
}
return Padding(
padding: const EdgeInsets.all(3.0),
child: AnimatedContainer(
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(2.0),
),
duration: Duration(milliseconds: 2165),
alignment: Alignment.center,
//color: Colors.red,
height: double.parse(_hight),
width: 29.0,
child: Text(
_hight,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: _hight.length == 1
? 19.0
: _hight.length == 2
? 19.0
: _hight.length == 3
? 16.0
: _hight.length == 4 ? 14.0 : 10.0),
),
));
},
);
}
}

Categories

Resources