Flutter - 如何提取内部带有 onPressed setState 的 Widget?
Flutter - How to Extract Widget with onPressed setState inside?
我想提取一个内部带有 onPressed
setState
的小部件,但我收到消息“无法提取对封闭 class 方法的引用。"
有办法吗?
我想将我的代码分成不同的小部件,以使其保持清晰。这是一个简化的代码示例:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Calculator(),
);
}
}
class Calculator extends StatefulWidget {
@override
_CalculatorState createState() => _CalculatorState();
}
class _CalculatorState extends State<Calculator> {
var myValue = 0;
void calculate() {
myValue = 12;
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: TextButton(
onPressed: () {
setState(() {
calculate();
});
},
child: Text(
'Button 001',
),
),
),
TextOutput(myValue: myValue),
],
),
);
}
}
class TextOutput extends StatelessWidget {
const TextOutput({
Key key,
@required this.myValue,
}) : super(key: key);
final int myValue;
@override
Widget build(BuildContext context) {
return Container(
child: Text(
myValue.toString(),
),
);
}
}
我想提取到单独的小部件中的部分:
Container(
child: TextButton(
onPressed: () {
setState(() {
calculate();
});
},
child: Text(
'Button 001',
),
),
),
Setstate 与您要刷新其状态的小部件有关。如果你把它提取到另一个地方,那么setState就是指新widget的状态。
在您的情况下,setState 只会更改封装您要提取的小部件及其子项的容器的状态,它不会向上迁移。
除非,您使用 exact type
寻找您想要的小部件的状态,然后触发那里的状态,但这是矫枉过正,比您目前拥有的要难得多,需要更多的代码.
您可以在提取小部件上使用 VoidCallback
来获取 onPressed
事件
class MyContainer extends StatelessWidget {
final VoidCallback onTap;
const MyContainer({
Key? key,
required this.onTap,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: TextButton(
onPressed: onTap,
child: Text(
'Button 001',
),
),
);
}
}
并使用喜欢
MyContainer(
onTap: () {
print("tapped");
setState(() {
calculate();
});
},
),
Flutter 为子部件和父部件之间的回调式事件提供 VoidCallback 和 Function(x)(其中 x 可以是不同的类型)。
简单你可以通过构造函数传递Function onPressed;
这是您提取的容器小部件:
class ExtractedContainer extends StatelessWidget {
final Function onPressed;
const ExtractedContainer({
Key key, @required this.onPressed,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: TextButton(
onPressed: () {
onPressed();
},
child: Text(
'Button 001',
),
),
);
}
}
这里是如何使用它:
@override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ExtractedContainer(onPressed: calculate,),
TextOutput(myValue: myValue),
],
),
);
}
您的完整代码示例
import 'package:flutter/material.dart';
class MyApp2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Calculator(),
);
}
}
class Calculator extends StatefulWidget {
@override
_CalculatorState createState() => _CalculatorState();
}
class _CalculatorState extends State<Calculator> {
var myValue = 0;
void calculate() {
myValue = 12;
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ExtractedContainer(onPressed: calculate,),
TextOutput(myValue: myValue),
],
),
);
}
}
class ExtractedContainer extends StatelessWidget {
final Function onPressed;
const ExtractedContainer({
Key key, @required this.onPressed,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: TextButton(
onPressed: () {
onPressed();
},
child: Text(
'Button 001',
),
),
);
}
}
class TextOutput extends StatelessWidget {
const TextOutput({
Key key,
@required this.myValue,
}) : super(key: key);
final int myValue;
@override
Widget build(BuildContext context) {
return Container(
child: Text(
myValue.toString(),
),
);
}
}
我想提取一个内部带有 onPressed
setState
的小部件,但我收到消息“无法提取对封闭 class 方法的引用。"
有办法吗?
我想将我的代码分成不同的小部件,以使其保持清晰。这是一个简化的代码示例:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Calculator(),
);
}
}
class Calculator extends StatefulWidget {
@override
_CalculatorState createState() => _CalculatorState();
}
class _CalculatorState extends State<Calculator> {
var myValue = 0;
void calculate() {
myValue = 12;
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: TextButton(
onPressed: () {
setState(() {
calculate();
});
},
child: Text(
'Button 001',
),
),
),
TextOutput(myValue: myValue),
],
),
);
}
}
class TextOutput extends StatelessWidget {
const TextOutput({
Key key,
@required this.myValue,
}) : super(key: key);
final int myValue;
@override
Widget build(BuildContext context) {
return Container(
child: Text(
myValue.toString(),
),
);
}
}
我想提取到单独的小部件中的部分:
Container(
child: TextButton(
onPressed: () {
setState(() {
calculate();
});
},
child: Text(
'Button 001',
),
),
),
Setstate 与您要刷新其状态的小部件有关。如果你把它提取到另一个地方,那么setState就是指新widget的状态。
在您的情况下,setState 只会更改封装您要提取的小部件及其子项的容器的状态,它不会向上迁移。
除非,您使用 exact type
寻找您想要的小部件的状态,然后触发那里的状态,但这是矫枉过正,比您目前拥有的要难得多,需要更多的代码.
您可以在提取小部件上使用 VoidCallback
来获取 onPressed
事件
class MyContainer extends StatelessWidget {
final VoidCallback onTap;
const MyContainer({
Key? key,
required this.onTap,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: TextButton(
onPressed: onTap,
child: Text(
'Button 001',
),
),
);
}
}
并使用喜欢
MyContainer(
onTap: () {
print("tapped");
setState(() {
calculate();
});
},
),
Flutter 为子部件和父部件之间的回调式事件提供 VoidCallback 和 Function(x)(其中 x 可以是不同的类型)。
简单你可以通过构造函数传递Function onPressed;
这是您提取的容器小部件:
class ExtractedContainer extends StatelessWidget {
final Function onPressed;
const ExtractedContainer({
Key key, @required this.onPressed,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: TextButton(
onPressed: () {
onPressed();
},
child: Text(
'Button 001',
),
),
);
}
}
这里是如何使用它:
@override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ExtractedContainer(onPressed: calculate,),
TextOutput(myValue: myValue),
],
),
);
}
您的完整代码示例
import 'package:flutter/material.dart';
class MyApp2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Calculator(),
);
}
}
class Calculator extends StatefulWidget {
@override
_CalculatorState createState() => _CalculatorState();
}
class _CalculatorState extends State<Calculator> {
var myValue = 0;
void calculate() {
myValue = 12;
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ExtractedContainer(onPressed: calculate,),
TextOutput(myValue: myValue),
],
),
);
}
}
class ExtractedContainer extends StatelessWidget {
final Function onPressed;
const ExtractedContainer({
Key key, @required this.onPressed,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: TextButton(
onPressed: () {
onPressed();
},
child: Text(
'Button 001',
),
),
);
}
}
class TextOutput extends StatelessWidget {
const TextOutput({
Key key,
@required this.myValue,
}) : super(key: key);
final int myValue;
@override
Widget build(BuildContext context) {
return Container(
child: Text(
myValue.toString(),
),
);
}
}