Flutter / Dart - I have a simple diabetic app but am new to programming, so struggling a lot, even after watching hours of Flutter youtube videos! My app currently has 4 input fields on one row and the result of a calculation of input1 - input2 below it. I would like to change this, so that the top row has Input / Input / Output (in similar boxes) and the second row has Input / Input / Output (in similar boxes). The code for my current app is shown below after some help on Stackoverflow. It has been suggested that I use the command "resultTextFieldController.text = resultOfCalculation;" to put the result in a text box, but my main issue is where to put that line as everywhere I have put it so far, the line gets underlined in red.
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";
_calculate() {
if (num1controller.text.isNotEmpty && num2controller.text.isNotEmpty) {
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(
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 20.0),
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(
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 20.0),
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'),
],
),
),
),
);
}
}
CodePudding user response:
Full Code
import 'package:flutter/material.dart';
import 'package:flutter/services.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 numR1C1controller =
TextEditingController(); //Changed name of the texteditingcontroller as Row as R and Column as C
TextEditingController numR1C2controller = TextEditingController();
TextEditingController numR1C3controller = TextEditingController();
TextEditingController numR2C1controller = TextEditingController();
TextEditingController numR2C2controller = TextEditingController();
TextEditingController numR2C3controller = TextEditingController();
String result = "0";
String result2 = "0";
_calculateR1() {
if (numR1C1controller.text.isNotEmpty &&
numR1C2controller.text.isNotEmpty) {
setState(() {
double sum = double.parse(numR1C1controller.text) -
double.parse(numR1C2controller.text);
numR1C3controller.text = sum.toStringAsFixed(1);
result = sum.toStringAsFixed(1);
});
}
}
_calculateR2() {
if (numR2C1controller.text.isNotEmpty &&
numR2C2controller.text.isNotEmpty) {
setState(() {
double sum = double.parse(numR2C1controller.text) -
double.parse(numR2C2controller.text);
numR2C3controller.text = sum.toStringAsFixed(1);
result2 = 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(
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 20.0),
onChanged: (value) => _calculateR1(),
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
controller: numR1C1controller,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Target Level',
hintText: 'Enter First Number',
),
),
),
const SizedBox(
width: 8,
),
Expanded(
child: TextField(
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 20.0),
onChanged: (value) => _calculateR1(),
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
controller: numR1C2controller,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Current Level',
hintText: 'Enter Second Number',
),
),
),
const SizedBox(
width: 8,
),
Expanded(
child: TextField(
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 20.0),
onChanged: (value) => _calculateR1(),
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
controller: numR1C3controller,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Result',
hintText: '',
),
),
),
const SizedBox(
width: 8,
),
],
),
const SizedBox(
height: 8,
),
Row(
children: [
Expanded(
child: TextField(
onChanged: (value) => _calculateR2(),
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
controller: numR2C1controller,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Current Meal carbs',
hintText: 'Enter Third Number',
),
),
),
const SizedBox(
width: 8,
),
Expanded(
child: TextField(
onChanged: (value) => _calculateR2(),
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
controller: numR2C2controller,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Current Meal carbs 2',
hintText: 'Enter Fourth Number',
),
),
),
const SizedBox(
width: 8,
),
Expanded(
child: TextField(
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 20.0),
onChanged: (value) => _calculateR2(),
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
controller: numR2C3controller,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Result',
hintText: '',
),
),
),
const SizedBox(
width: 8,
),
],
),
Text(
'Difference between Target Level and Current Level: $result'),
],
),
),
),
);
}
}
Output
Add this line to the textfield widget to allow only numbers to be inputted in the text field.
inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly],
Hope this helps. Happy Coding :)