[英]Flutter 'setState' of other Widget
i want to code a POS for german 'Fischbrötchen'.我想为德语“Fischbrötchen”编写一个 POS。 My problem is that the "View" of the Ordertabel dosn't update.我的问题是 Ordertabel 的“视图”没有更新。 I tried man things but nothing worked... can someone help me to point out my Problem?我尝试了一些人的事情,但没有任何效果......有人可以帮我指出我的问题吗? So when i click a button a Order should add to the Orders List and then update the View to display the order.因此,当我单击一个按钮时,订单应添加到订单列表中,然后更新视图以显示订单。
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoApp(
home: MyHomePage(),
debugShowCheckedModeBanner: false,
theme: CupertinoThemeData(
brightness: Brightness.light, primaryColor: Colors.black54),
);
}
}
ValueNotifier<int> KundenId = ValueNotifier<int>(0);
List<Map<String, dynamic>> orders = [];
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
final List Getraenke = ["Fritz", "Wasser", "Bier"];
List<Map<String, dynamic>> items = [
{'name': 'Möltenorter', 'price': '4 Euro'},
{'name': 'Matjes', 'price': '4 Euro'},
{'name': 'Bismarkt', 'price': '4 Euro'},
{'name': 'Krabben', 'price': '5,50 Euro'},
{'name': 'Lachs', 'price': '5.50 Euro'},
{'name': 'Lachs Kalt', 'price': '5.50 Euro'},
];
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: RightSideContainer(),
);
}
}
class RightSideContainer extends StatefulWidget {
@override
State<StatefulWidget> createState() => RightSideContainerState();
}
class RightSideContainerState extends State<RightSideContainer> {
@override
Widget build(BuildContext context) {
return Row(
children: [
//left side, eingabe
Column(
children: [
Text("Kasse"),
Container(
height: 600,
width: MediaQuery.of(context).size.width / 2,
child: Padding(
padding: EdgeInsets.all(5.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.black54,
),
alignment: AlignmentDirectional.topStart,
child: OrderTable(),
))),
],
),
//right side, Ausgabe
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(0),
color: Colors.black.withOpacity(0.5),
),
width: MediaQuery.of(context).size.width / 2,
alignment: Alignment.centerRight,
child: Column(
children: [
Container(
height: 500,
color: Colors.red,
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4),
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return ButtonPrefab(items_: items[index]);
}),
),
],
))
],
);
}
}
class ButtonPrefab extends StatelessWidget {
final Map<String, dynamic> items_;
const ButtonPrefab({required this.items_});
void addOrder(name, price) {
orders.add({
'kundenId': 0,
'bestellung': name,
'price': price,
});
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: CupertinoButton(
child: Text(items_['name']),
color: Colors.black54,
padding: EdgeInsets.all(3),
onPressed: () {
print(orders);
addOrder("name", 2.4);
KundenId.value++;
print(KundenId.value);
},
),
);
}
}
class OrderTable extends StatefulWidget {
@override
State<OrderTable> createState() => _OrderTableState();
}
class _OrderTableState extends State<OrderTable> {
@override
void initState() {
super.initState();
setState(() {});
}
void update() {
setState(() {});
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return DataTable(
columnSpacing: 20,
columns: [
DataColumn(
label: Text(
'Kunden ID',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
DataColumn(
label: Text(
'Bestellung',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
DataColumn(
label: Text(
'Preis',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
],
rows: orders
.map(
(order) => DataRow(
cells: [
DataCell(
Text(
order['kundenId'].toString(),
style: TextStyle(fontSize: 16),
),
),
DataCell(
Text(
order['bestellung'],
style: TextStyle(fontSize: 16),
),
),
DataCell(
Text(
order['price'].toString(),
style: TextStyle(fontSize: 16),
),
),
],
),
)
.toList(),
);
})
],
),
);
}
}
I tried to use 'set State' in my Statefull Widget but is dosn't change anything..我尝试在我的 Statefull Widget 中使用“set State”但是没有改变任何东西..
There is so many problems here, that I cannot list them one by one.这里的问题太多了,我无法一一列举。
The basic underlying problem here is that you think having a global variable is a good method to keep your state. It is not.这里的基本潜在问题是您认为拥有全局变量是保留 state 的好方法。事实并非如此。 Never has been.从来没有。 In no programming language in the last quarter of a century.在过去的四分之一个世纪里没有编程语言。
To hold your state (in your case I guess it's orders
) use one of the state management patterns .要保留您的 state(在您的情况下,我猜它是orders
),请使用state 管理模式之一。
I suggest taking a look at Provider
first.我建议先看看Provider
。 Not because it's the best, but because it is the easiest and explains your problem clearly:不是因为它是最好的,而是因为它是最简单的并且清楚地解释了您的问题:
Simple app state management 简单的应用程序 state 管理
Once your applications get larger, my personal preference is BLoC, but that is a little to complex for this problem.一旦您的应用程序变得更大,我个人的偏好是 BLoC,但这对于这个问题来说有点复杂。
Deleted my previous answer and tested your code... and got it working now.删除了我之前的回答并测试了您的代码......现在它开始工作了。
I see you have a Function named update() and you're even using it there, but should use it somewhere else as a callback Function. A callback Function helps you to edit values in your "previous" Widget that called this Widget.我看到您有一个名为 update() 的 Function,您甚至在那里使用它,但应该在其他地方使用它作为回调 Function。回调 Function 可帮助您编辑调用此 Widget 的“上一个”Widget 中的值。 Read more here: How to pass callback in Flutter在此处阅读更多信息: 如何在 Flutter 中传递回调
Also you have setState() in initState.你在 initState 中也有 setState() 。 Don't see the reason to have this there either.也看不出在那里有这个的原因。 You should use setState in initState only for some kind of asyncronus reason, as explained here: Importance of Calling SetState inside initState您应该仅出于某种异步原因在 initState 中使用 setState,如此处解释: Importance of Calling SetState inside initState
Call setState in "previous" Widget on button press after adding your item by using a callback Function (for short keeping, here is only the modified code):在使用回调 Function 添加您的项目后,在按钮按下时调用“上一个”小部件中的 setState(为了简短起见,这里仅提供修改后的代码):
class RightSideContainerState extends State<RightSideContainer> {
void update() { //this is a new Function
setState(() {});
}
@override
Widget build(BuildContext context) {
return Row(
children: [
//left side, eingabe
Column(
children: [
Text("Kasse"),
Container(
height: 600,
width: MediaQuery.of(context).size.width / 2,
child: Padding(
padding: EdgeInsets.all(5.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.black54,
),
alignment: AlignmentDirectional.topStart,
child: OrderTable(),
))),
],
),
//right side, Ausgabe
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(0),
color: Colors.black.withOpacity(0.5),
),
width: MediaQuery.of(context).size.width / 2,
alignment: Alignment.centerRight,
child: Column(
children: [
Container(
height: 500,
color: Colors.red,
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4),
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return ButtonPrefab(items_: items[index], callbackFunction: update); //give the "update (setState)" Function to the "next" Widget for calling it later
}),
),
],
))
],
);
}
}
class ButtonPrefab extends StatelessWidget {
final Map<String, dynamic> items_;
final Function callbackFunction; //get the callback Function of the calling Widget
const ButtonPrefab({required this.items_, required this.callbackFunction}); //get the callback Function of the calling Widget
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: CupertinoButton(
child: Text(items_['name']),
color: Colors.black54,
padding: EdgeInsets.all(3),
onPressed: () {
print(orders);
// addOrder("name", 2.4); // you are always giving "name" and 2.4, but probably need to give the item that's being pushed
addOrder(items_['name'], items_['price']); //like this
KundenId.value++;
print(KundenId.value);
callbackFunction(); //this is the "update" Function I created in the calling Widget, but in this Widget it has a name "callbackFunction"
},
),
);
}
}
class _OrderTableState extends State<OrderTable> {
@override
void initState() {
super.initState();
// setState(() {}); // not necessary
}
// void update() { // not necessary
// setState(() {});
// }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.