3

I´m learning flutter and as a first app I chose to make a calculator. I have got the layout set and now I need to do some work with data. The core of the problem is that I would like to change output (which is StatefullWidget) every time I press a button.

This is my main.dart where I use my custom widgets OutputWindow and Numberlane.

import 'package:flutter/material.dart'; import 'package:study_project/NumberLane.dart'; import 'NumberLane.dart'; import 'OutputWindow.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. var custom = OutputWindow(); //Function f = custom.outputText; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( centerTitle: true, title: const Text("calculator"), titleTextStyle: const TextStyle( fontWeight: FontWeight.bold, fontSize: 25, )), body: Column( //mainAxisAlignment: MainAxisAlignment.center,' crossAxisAlignment: CrossAxisAlignment.stretch, children: [ //textoutput Expanded(child: OutputWindow()), //input Expanded( child: NumberLane(4), ), Expanded( child: NumberLane(3), ), Expanded( child: NumberLane(2), ), Expanded( child: NumberLane(1), ), ]))); } } 

Numberlane is there just to make the code more readable and its only purpose is to fill rows with another custom class Button

import 'package:flutter/material.dart'; import 'Button.dart'; class NumberLane extends StatelessWidget { int positioning = 0; NumberLane(this.positioning); @override Widget build(BuildContext context) { if (positioning == 1) { return Row( //crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded(child: Button(".")), Expanded(child: Button("0")), Expanded(child: Button("=")), Expanded(child: Button("/")), ], ); } else if (positioning == 2) { return Row( //crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded(child: Button("1")), Expanded(child: Button("2")), Expanded(child: Button("3")), Expanded(child: Button("+")), ], ); } else if (positioning == 3) { return Row( //crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded(child: Button("4")), Expanded(child: Button("5")), Expanded(child: Button("6")), Expanded(child: Button("-")), ], ); } else if (positioning == 4) { return Row( //crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded(child: Button("7")), Expanded(child: Button("8")), Expanded(child: Button("9")), Expanded(child: Button("*")), ], ); } else {} } } 

And here comes the problem. I have my TextButtons and from onPressed I need to call outputText method which is property of StatefullWidget OutputWindow. I would ideally like to change OutputWindow every time a button is tapped.

**Button

import 'package:flutter/material.dart'; import 'OutputWindow.dart'; class Button extends StatelessWidget { String description; //final Function outputText; Button(this.description) {} @override Widget build(BuildContext context) { return Container( width: double.infinity, height: double.infinity, child: TextButton( onPressed: () => {/*****here********/ }, style: TextButton.styleFrom( primary: const Color.fromARGB(255, 227, 100, 61)), child: Text( description, style: const TextStyle(color: Color.fromARGB(255, 235, 88, 43)), ), )); } } 

**OutputWindow

import 'package:flutter/material.dart'; import 'package:study_project/Button.dart'; import 'NumberLane.dart'; import 'main.dart'; class OutputWindow extends StatefulWidget { @override State<StatefulWidget> createState() { // TODO: implement createState return OutputWindowState(); } } class OutputWindowState extends State<OutputWindow> { String output = "0"; void outputText(String write) { setState(() { if (output == "0" || write == "." || write == "+" || write == "-" || write == "*" || write == "/" || write == "=") { output = write; } else if (write != "." && write != "+" && write != "-" && write != "*" && write != "/" && write != "=") { output += write; } }); } @override Widget build(BuildContext context) { return Text(output, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 35, color: Colors.black87, )); } } 

I have tried importing all packages and files but still couldn´t call the method and instantiation of my OutputWindow and calling the method via Instance.method(). Another thing that came my to mind is to pass function via pointer to constructor but that works only down the widget tree and I can´t get the method from OutputWindow to main.dart.

Thank you so much for your help.

1

1 Answer 1

2

I have added some code so it will work.

import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp(home: Home()); } } String outputText = ""; class Home extends StatefulWidget { const Home({ Key? key, }) : super(key: key); @override State<Home> createState() => _HomeState(); } class _HomeState extends State<Home> { String output = ''; @override void initState() { super.initState(); outputText = output; } changeOutut(String value) { outputText = value; setState(() { output = value; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, title: const Text("calculator"), titleTextStyle: const TextStyle( fontWeight: FontWeight.bold, fontSize: 25, )), body: Column( //mainAxisAlignment: MainAxisAlignment.center,' crossAxisAlignment: CrossAxisAlignment.stretch, children: [ //textoutput Expanded( child: OutputWindow( output: output, )), //input Expanded( child: NumberLane(4, changeOutut), ), Expanded( child: NumberLane(3, changeOutut), ), Expanded( child: NumberLane(2, changeOutut), ), Expanded( child: NumberLane(1, changeOutut), ), ])); } } class NumberLane extends StatelessWidget { final int positioning; final dynamic changeOutut; const NumberLane(this.positioning, this.changeOutut, {Key? key}) : super(key: key); add(String value) { changeOutut(outputText + value); } @override Widget build(BuildContext context) { if (positioning == 1) { return Row( //crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded(child: Button(".",add)), Expanded(child: Button("0",add)), Expanded(child: Button("=",add)), Expanded(child: Button("/",add)), ], ); } else if (positioning == 2) { return Row( //crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded(child: Button("1",add)), Expanded(child: Button("2",add)), Expanded(child: Button("3",add)), Expanded(child: Button("+",add)), ], ); } else if (positioning == 3) { return Row( //crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded(child: Button("4",add)), Expanded(child: Button("5",add)), Expanded(child: Button("6",add)), Expanded(child: Button("-",add)), ], ); } else if (positioning == 4) { return Row( //crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded(child: Button("7",add)), Expanded(child: Button("8",add)), Expanded(child: Button("9",add)), Expanded(child: Button("*",add)), ], ); } else { return SizedBox(); } } } class Button extends StatelessWidget { final String description; final dynamic add; const Button(this.description,this.add, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Container( width: double.infinity, height: double.infinity, child: TextButton( onPressed: () => { add(description), }, style: TextButton.styleFrom( primary: const Color.fromARGB(255, 227, 100, 61)), child: Text( description, style: const TextStyle(color: Color.fromARGB(255, 235, 88, 43)), ), )); } } class OutputWindow extends StatelessWidget { final String output; const OutputWindow({Key? key, required this.output}) : super(key: key); @override Widget build(BuildContext context) { return Text(output, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 35, color: Colors.black87, )); } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.