美文网首页flutter学习
Flutter-->如何通过setState刷新Dialog的内

Flutter-->如何通过setState刷新Dialog的内

作者: 谢尔顿 | 来源:发表于2019-04-08 10:31 被阅读0次

1. 提出问题

image.png

上面是我们常见的一个效果图,按照常理我们的实现代码如下:

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  List<String> cuntries = <String>[
    '北京',
    '上海',
    '成都',
    '西安',
    '太原',
    '云南',
  ];
  int _selectedCountryIndex = 0;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _showDialog();
    });
  }

  _showDialog() async {
    await showDialog(
        context: context,
        builder: (BuildContext context) {
          return new CupertinoAlertDialog(
            title: new Text('请选择'),
            actions: <Widget>[
              new CupertinoDialogAction(
                  isDestructiveAction: true,
                  onPressed: () {
                    Navigator.of(context).pop('取消');
                  },
                  child: new Text('取消')),
              new CupertinoDialogAction(
                  isDestructiveAction: true,
                  onPressed: () {
                    Navigator.of(context).pop('确定');
                  },
                  child: new Text('确定')),
            ],
            content: new SingleChildScrollView(
              child: new Material(
                child: _buildList(),
              ),
            ),
          );
        });
  }

  _buildList() {
    if (cuntries.length == 0) return Container();
    return new Column(
      children:
          new List<RadioListTile<int>>.generate(cuntries.length, (int index) {
        return new RadioListTile(
            value: index,
            groupValue: _selectedCountryIndex,
            title: new Text(cuntries[index]),
            onChanged: (int value) {
              setState(() {
                _selectedCountryIndex = value;
              });
            });
      }),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(),
      // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

运行之后点击条目,发现并不能刷新dialog的界面。

2. 解决办法

我们可以将dialog的内容部分抽取出来用一个StatefulWidget来实现,如下所示:

import 'package:flutter/material.dart';

class MyDialogContent extends StatefulWidget {
  final List<String> cuntries;
  MyDialogContent({Key key, this.cuntries}) : super(key: key);
  @override
  _MyDialogContentState createState() => _MyDialogContentState();
}

class _MyDialogContentState extends State<MyDialogContent> {
  int _selectedIndex = 0;

  _getContent() {
    if (widget.cuntries.length == 0) {
      return new Container();
    }
    return new Column(
      children: new List<RadioListTile<int>>.generate(widget.cuntries.length,
          (int index) {
        return new RadioListTile(
            value: index,
            groupValue: _selectedIndex,
            title: new Text(widget.cuntries[index]),
            onChanged: (int value) {
              setState(() {
                _selectedIndex = value;
              });
            });
      }),
    );
  }

  @override
  Widget build(BuildContext context) {
    return _getContent();
  }
}

将问题代码中的_buildList方法替换成下面代码

 new MyDialogContent(
                  cuntries: cuntries,
                )

3.解决后的最终代码

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  List<String> cuntries = <String>[
    '北京',
    '上海',
    '成都',
    '西安',
    '太原',
    '云南',
  ];
  int _selectedCountryIndex = 0;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _showDialog();
    });
  }

  _showDialog() async {
    await showDialog(
        context: context,
        builder: (BuildContext context) {
          return new CupertinoAlertDialog(
            title: new Text('请选择'),
            actions: <Widget>[
              new CupertinoDialogAction(
                  isDestructiveAction: true,
                  onPressed: () {
                    Navigator.of(context).pop('取消');
                  },
                  child: new Text('取消')),
              new CupertinoDialogAction(
                  isDestructiveAction: true,
                  onPressed: () {
                    Navigator.of(context).pop('确定');
                  },
                  child: new Text('确定')),
            ],
            content: new SingleChildScrollView(
              child: new Material(
                child: new MyDialogContent(
                  cuntries: cuntries,
                ),
              ),
            ),
          );
        });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(),
    );
  }
}

相关文章

网友评论

    本文标题:Flutter-->如何通过setState刷新Dialog的内

    本文链接:https://www.haomeiwen.com/subject/emoyiqtx.html