A simple app which returns a TextButton() with given name and given color.
Problem: I have to choose the color first and then name the card but can't name the card and then choose the color.
I'd get an LateinitializationError with late String cardTitle; and with String? cardTitle; a: Null check operator used on a null value
import 'package:flutter/material.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
import 'package:provider/provider.dart';
import 'package:cards/Models/card_data.dart';
Color pickerColor = Color(0xffFAFAFA);
class AddCard extends StatefulWidget {
@override
State<AddCard> createState() => _AddCardState();
}
class _AddCardState extends State<AddCard> {
void changeColor(Color color) {
setState(() => pickerColor = color);
}
TextEditingController myController = TextEditingController();
@override
void dispose() {
myController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
late Color newCardColor = Color(0xffFAFAFA);
String? cardTitle;
return Container(
color: Color(0xff757575),
child: Container(
padding: EdgeInsets.all(20.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(140, 0, 140, 20),
child: Container(
decoration: BoxDecoration(
color: Colors.grey.shade700,
borderRadius: BorderRadius.circular(5)),
height: 4,
width: 70,
),
),
Row(
children: [
Expanded(
flex: 3,
child: Material(
borderRadius: BorderRadius.circular(15),
elevation: 10,
child: TextFormField(
textAlign: TextAlign.center,
autofocus: true,
controller: myController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: BorderSide.none),
filled: true,
fillColor: pickerColor,
hintStyle: TextStyle(
color: useWhiteForeground(pickerColor)
? const Color(0xffffffff)
: const Color(0xff000000),
fontSize: 18),
hintText: 'Nenne deine Neue Karte'),
style: (TextStyle(
color: useWhiteForeground(pickerColor)
? const Color(0xffffffff)
: const Color(0xff000000),
fontSize: 20)),
onChanged: (newText) {
cardTitle = newText;
},
),
),
),
Expanded(
child: SizedBox(
height: 65,
child: Padding(
padding: EdgeInsets.only(left: 20),
child: TextButton(
style: TextButton.styleFrom(
shadowColor: pickerColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)),
elevation: 10,
backgroundColor: pickerColor),
child: Icon(
Icons.done,
color: useWhiteForeground(pickerColor)
? const Color(0xffffffff)
: const Color(0xff000000),
size: 40,
),
onPressed: () {
Provider.of<MyCardData>(context, listen: false)
.addCard(
cardTitle!,
newCardColor,
);
Navigator.pop(context);
}),
),
),
),
],
),
Padding(
padding: EdgeInsets.fromLTRB(10, 15, 10, 5),
child: Container(
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(5)),
height: 2,
width: 70,
),
),
Padding(
padding: EdgeInsets.only(top: 10),
child: MaterialPicker(
pickerColor: pickerColor,
onColorChanged: changeColor,
),
),
SizedBox(
height: 20,
)
],
),
),
);
}
}
more on my git git
CodePudding user response:
fix this:
remove
late
initialization when you set the value.late
means that, you promise to the state that the value will be set later before used.late Color newCardColor = Color(0xffFAFAFA);
to thisColor newCardColor = Color(0xffFAFAFA);
Move cardTitle outside the
build
method. because you want to update the state value later whenonChaged
in textField. If you initialize inisde the build method, the state value will not changed.call
setState((){})
to update your valuecardTitle
.
here full code:
Color pickerColor = Color(0xffFAFAFA);
class AddCard extends StatefulWidget {
@override
State<AddCard> createState() => _AddCardState();
}
class _AddCardState extends State<AddCard> {
void changeColor(Color color) {
setState(() => pickerColor = color);
}
TextEditingController myController = TextEditingController();
Color newCardColor = Color(0xffFAFAFA);
String? cardTitle;
@override
void dispose() {
myController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
color: Color(0xff757575),
child: Container(
padding: EdgeInsets.all(20.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(140, 0, 140, 20),
child: Container(
decoration: BoxDecoration(
color: Colors.grey.shade700,
borderRadius: BorderRadius.circular(5)),
height: 4,
width: 70,
),
),
Row(
children: [
Expanded(
flex: 3,
child: Material(
borderRadius: BorderRadius.circular(15),
elevation: 10,
child: TextFormField(
textAlign: TextAlign.center,
autofocus: true,
controller: myController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: BorderSide.none),
filled: true,
fillColor: pickerColor,
hintStyle: TextStyle(
color: useWhiteForeground(pickerColor)
? const Color(0xffffffff)
: const Color(0xff000000),
fontSize: 18),
hintText: 'Nenne deine Neue Karte'),
style: (TextStyle(
color: useWhiteForeground(pickerColor)
? const Color(0xffffffff)
: const Color(0xff000000),
fontSize: 20)),
onChanged: (newText) {
cardTitle = newText;
setState((){});
},
),
),
),
Expanded(
child: SizedBox(
height: 65,
child: Padding(
padding: EdgeInsets.only(left: 20),
child: TextButton(
style: TextButton.styleFrom(
shadowColor: pickerColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)),
elevation: 10,
backgroundColor: pickerColor),
child: Icon(
Icons.done,
color: useWhiteForeground(pickerColor)
? const Color(0xffffffff)
: const Color(0xff000000),
size: 40,
),
onPressed: () {
Provider.of<MyCardData>(context, listen: false)
.addCard(
cardTitle ?? '',
newCardColor,
); // when card title is null, it will set empty string
Navigator.pop(context);
}),
),
),
),
],
),
Padding(
padding: EdgeInsets.fromLTRB(10, 15, 10, 5),
child: Container(
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(5)),
height: 2,
width: 70,
),
),
Padding(
padding: EdgeInsets.only(top: 10),
child: MaterialPicker(
pickerColor: pickerColor,
onColorChanged: changeColor,
),
),
SizedBox(
height: 20,
)
],
),
),
);
}
}