简体   繁体   English

Flutter 其他Widget的'setState'

[英]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.

相关问题 Flutter:使用带有 AnimatedSwitcher 的 setstate 时未重建小部件 - Flutter: Widget not rebuilt when using setstate with AnimatedSwitcher 从 Flutter 中的另一个 dart 文件在有状态小部件 class 下使用 SetState 方法调用 void - Call void with SetState method under stateful widget class from another dart file in Flutter 如何将其他 dart 文件导入 flutter 中的有状态小部件? - How can I import other dart file to stateful widget in flutter? 从 ListView 或其他 Scroll Widget (Flutter) 检测 Scroll 的开始 - Detect start of Scroll from ListView or other Scroll Widget (Flutter) Flutter 当我调用我新创建的自定义小部件时,其他小部件不显示 - Flutter other widget doesn`t show when I call my new created custom widget 来自不同屏幕的 Flutter setState - Flutter setState from a different Screen Flutter:GestureDetector 中的 setState() 不起作用 - Flutter: setState() inside GestureDetector is not working Flutter SliverAppBar 和 FlexibleSpaceBar 在向上滚动时呈现与 FlexibleSpaceBar 的标题参数不同的小部件 - Flutter SliverAppBar and FlexibleSpaceBar which Renders a different widget other than title param of FlexibleSpaceBar on scrolling up Flutter - 如何从其他小部件访问 DropDown 中当前选定的项目? - Flutter - How can I access current selected item in DropDown from other widget? Flutter 中的 Widget 是什么? - What is a Widget in Flutter?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM