用状态重置计数器

时间:2019-05-15 17:30:47

标签: flutter

我只是在学习Flutter,而且似乎只能从事一项很简单的任务,但是我一生都无法解决。我要做的就是将所有计数器都重置为0。也许我正在以错误的方式进行操作,这就是为什么我被卡住了。有人可以帮忙吗?


class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {

  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations(
        [DeviceOrientation.landscapeRight, DeviceOrientation.landscapeLeft]);

    return MaterialApp(
      theme: ThemeData.light(),
      home: Scaffold(
        backgroundColor: Colors.white,
        body: CustomScrollView(
          slivers: <Widget>[
            SliverAppBar(
              leading: IconButton(
                  icon: Image.asset('assets/thumbsup.png'),
                  onPressed: () {
                    //reset all counters
                  }),
              expandedHeight: 150.0,
              backgroundColor: Colors.red,
              pinned: true,
              floating: true,
              flexibleSpace: FlexibleSpaceBar(
                title: Text('Welcome to Logie & Lana\'s Drive Thru', style: TextStyle(fontSize: 32),),
                centerTitle: false,
                collapseMode: CollapseMode.parallax,
              ),
            ),
            SliverGrid.count(
              mainAxisSpacing: 10.0,
              crossAxisCount: 4,
              crossAxisSpacing: 10.0,
              childAspectRatio: 1.2,
              children: <Widget>[
                MyCounter('bigmac-small.png'),
                MyCounter('mcdonalds-fries.png'),
                MyCounter('mcnuggets.png'),
                MyCounter('coke.png'),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

class MyCounter extends StatefulWidget {
  final String image;

  MyCounter(this.image);

  @override
  State<StatefulWidget> createState() {
    return _MyCounter(image);
  }
}


class _MyCounter extends State<MyCounter> {
  int counter;
  String image;

  _MyCounter(this.image);

  @override
  Widget build(BuildContext context) {

    return RaisedButton(
      highlightColor: Colors.yellowAccent,
      splashColor: Colors.red,
      color: Colors.white,
      onPressed: () {
        setState(() {
          counter++;
        });
      },
      child: Column(
        children: <Widget>[
          Image.asset(
            'assets/$image',
            height: 150.0,
          ),
          Text(
            '$counter',
            style: TextStyle(fontSize: 36),
          )
        ],
      ),
    );
  }
}

就像我说的那样,它应该非常简单,只不过是带有计数器的几个按钮而已,但它使我发疯。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

您遇到的问题是,您尝试从父窗口小部件更改子窗口小部件的状态,如果需要,可以通过流来完成,但是如果您只是开始,则将所有需要更改的信息保留在父窗口中小部件,并在需要更改时从父小部件调用setState。

为此,您可以将MyCounter小部件更改为无状态小部件,并在初始化时将其传递给闭包,该闭包调用setState方法并使用_MyAppState小部件中的setState方法更新相应的count变量。如果有什么让您感到困惑的问题,请随时发表评论,我会尽力解释。

这里是一个例子:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    //SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeRight, DeviceOrientation.landscapeLeft]);

    return MaterialApp(
      theme: ThemeData.light(),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var images = Map<String,int>();

  @override
  void initState() {
    super.initState();

    images['bigmac-small.png'] = 0;
    images['mcdonalds-fries.png'] = 0;
    images['mcnuggets.png'] = 0;
    images['coke.png'] = 0;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.white,
        body: CustomScrollView(
          slivers: <Widget>[
            SliverAppBar(
              leading: IconButton(
                  icon: Image.asset('assets/thumbsup.png'),
                  onPressed: () {
                    setState((){
                      images['bigmac-small.png'] = 0;
                      images['mcdonalds-fries.png'] = 0;
                      images['mcnuggets.png'] = 0;
                      images['coke.png'] = 0;
                    });
                  }),
              expandedHeight: 150.0,
              backgroundColor: Colors.red,
              pinned: true,
              floating: true,
              flexibleSpace: FlexibleSpaceBar(
                title: Text('Welcome to Logie & Lana\'s Drive Thru', style: TextStyle(fontSize: 32),),
                centerTitle: false,
                collapseMode: CollapseMode.parallax,
              ),
            ),
            SliverGrid.count(
              mainAxisSpacing: 10.0,
              crossAxisCount: 4,
              crossAxisSpacing: 10.0,
              childAspectRatio: 1.2,
              children: <Widget>[
                MyCounter('bigmac-small.png',images['bigmac-small.png'],() => setState((){images['bigmac-small.png']++;})),
                MyCounter('mcdonalds-fries.png',images['mcdonalds-fries.png'],() => setState((){images['mcdonalds-fries.png']++;})),
                MyCounter('mcnuggets.png',images['mcnuggets.png'],() => setState((){images['mcnuggets.png']++;})),
                MyCounter('coke.png',images['coke.png'],() => setState((){images['coke.png']++;})),
              ],
            ),
          ],
        )
    );
  }
}

class MyCounter extends StatelessWidget {
  final String image;
  final int count;
  final VoidCallback onPressed;

  MyCounter(this.image, this.count, this.onPressed);

  @override
  Widget build(BuildContext context) {

    return RaisedButton(
      highlightColor: Colors.yellowAccent,
      splashColor: Colors.red,
      color: Colors.white,
      onPressed: () => onPressed(),
      child: Column(
        children: <Widget>[
          Image.asset(
            'assets/$image',
            height: 150.0,
          ),
          Text(
            '$count',
            style: TextStyle(fontSize: 36),
          )
        ],
      ),
    );
  }
}