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
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 this
Color newCardColor = Color(0xffFAFAFA);
Move cardTitle outside the build
method. because you want to update the state value later when onChaged
in textField. If you initialize inisde the build method, the state value will not changed.
call setState((){})
to update your value cardTitle
.
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,
)
],
),
),
);
}
}