Flutter / Dart - I have a simple app but am new to programming, so struggling.
Currently, the setup is with all the TextInput boxes in a Column. I would like to change this to having them in a Row. I assumed this would be easy by simply replacing the Word Column with Row on line 44. But it doesn't work and when I try to run it, the "errors_patch.dart" page opens (which I have never seen before) with a highlighted error on line 51 "int assertionStart, int assertionEnd, Object? message);".
How can I simply change from Column to Row?
How can I have the result show in real time rather than needing to click on the "Subtraction" button to get it?
Many thanks in advance.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
const appTitle = 'Help with a meal....';
return MaterialApp(
debugShowCheckedModeBanner: false,
title: appTitle,
home: Scaffold(
appBar: AppBar(
title: const Text(appTitle),
backgroundColor: Colors.grey,
foregroundColor: Colors.black,
),
body: const AddTwoNumbers(),
),
);
}
}
class AddTwoNumbers extends StatefulWidget {
const AddTwoNumbers({super.key});
@override
// ignore: library_private_types_in_public_api
_AddTwoNumbersState createState() => _AddTwoNumbersState();
}
class _AddTwoNumbersState extends State<AddTwoNumbers> {
TextEditingController num1controller = TextEditingController();
TextEditingController num2controller = TextEditingController();
TextEditingController num3controller = TextEditingController();
TextEditingController num4controller = TextEditingController();
String result = "0";
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
TextField(
keyboardType: const TextInputType.numberWithOptions(decimal: true),
controller: num1controller,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Target Level',
hintText: 'Enter First Number',
),
),
const SizedBox(
height: 8,
),
TextField(
keyboardType: const TextInputType.numberWithOptions(decimal: true),
controller: num2controller,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Current Level',
hintText: 'Enter Second Number',
),
),
const SizedBox(
height: 8,
),
TextField(
keyboardType: const TextInputType.numberWithOptions(decimal: true),
controller: num3controller,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Current Meal carbs',
hintText: 'Enter Third Number',
),
),
const SizedBox(
height: 8,
),
TextField(
keyboardType: const TextInputType.numberWithOptions(decimal: true),
controller: num4controller,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Current Meal carbs 2',
hintText: 'Enter Fourth Number',
),
),
const SizedBox(
height: 8,
),
Wrap(children: [
ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
backgroundColor: Colors.purple),
child: const Text("Subtraction"),
onPressed: () {
setState(() {
double sum = double.parse(num1controller.text) -
double.parse(num2controller.text);
result = sum.toStringAsFixed(1);
});
},
),
const SizedBox(
height: 20,
width: 20,
),
]),
Text('Difference between Target Level and Current Level: $result'),
],
),
);
}
}
CodePudding user response:
There are many ways to do what you're trying to achieve. For changing Column to Rows, you can use a container with a column as a child and rows as children in it. You can see the documentation for further assistance.
For your second question, you can use onChanged() callback or you can use TextEditingController to see the realtime changes in your TextField.
CodePudding user response:
Since you are switching to Row
it doesn't know the width of the TextField
s, so you need to wrap them with Expanded
or Flexible
widgets to make them take the space they need (or you can give them some fixed width if you wish), something like in the solution below. And the answer to the second question is also in the solution, you just call the calculate method on every TextField
change.
class AddTwoNumbers extends StatefulWidget {
const AddTwoNumbers({Key? key}) : super(key: key);
@override
// ignore: library_private_types_in_public_api
_AddTwoNumbersState createState() => _AddTwoNumbersState();
}
class _AddTwoNumbersState extends State<AddTwoNumbers> {
TextEditingController num1controller = TextEditingController();
TextEditingController num2controller = TextEditingController();
TextEditingController num3controller = TextEditingController();
TextEditingController num4controller = TextEditingController();
String result = "0";
_calculate() {
setState(() {
double sum =
double.parse(num1controller.text) - double.parse(num2controller.text);
result = sum.toStringAsFixed(1);
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Container(
padding: const EdgeInsets.all(10.0),
child: Column(
children: [
Row(
children: <Widget>[
Expanded(
child: TextField(
onChanged: (value) => _calculate(),
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
controller: num1controller,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Target Level',
hintText: 'Enter First Number',
),
),
),
const SizedBox(
width: 8,
),
Expanded(
child: TextField(
onChanged: (value) => _calculate(),
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
controller: num2controller,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Current Level',
hintText: 'Enter Second Number',
),
),
),
const SizedBox(
width: 8,
),
Expanded(
child: TextField(
onChanged: (value) => _calculate(),
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
controller: num3controller,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Current Meal carbs',
hintText: 'Enter Third Number',
),
),
),
const SizedBox(
width: 8,
),
Expanded(
child: TextField(
onChanged: (value) => _calculate(),
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
controller: num4controller,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Current Meal carbs 2',
hintText: 'Enter Fourth Number',
),
),
),
const SizedBox(
width: 8,
),
],
),
Text(
'Difference between Target Level and Current Level: $result'),
],
),
),
),
);
}
}