我正在学习 flutter,作为第一个应用程序,我选择制作一个计算器。我已经设置了布局,现在需要对数据进行一些处理。问题的核心是我想在每次按下按钮时更改输出(即 StatefullWidget)。
这是我的 main.dart,我在其中使用自定义小部件 OutputWindow 和 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 的存在只是为了使代码更具可读性,其唯一目的是使用另一个自定义类 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 {}
}
}
问题来了。我有我的 TextButtons,并且从 onPressed 中我需要调用 outputText 方法,该方法是 StatefullWidget OutputWindow 的属性。理想情况下,我希望每次点击按钮时都更改 OutputWindow。
**按钮
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)),
),
));
}
}
**输出窗口
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,
));
}
}
我已尝试导入所有包和文件,但仍然无法调用 OutputWindow 的方法和实例化以及通过 Instance.method() 调用该方法。我想到的另一件事是通过指针传递函数到构造函数,但这只适用于小部件树,我无法从 OutputWindow 获取方法到 main.dart。
非常感谢您的帮助。
最佳答案
我添加了一些代码,因此它可以工作。
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,
));
}
}
关于flutter - 如何从Stateless类中的onPressed调用StatefulWidget的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72947889/