如何正确使用onPress的异步功能

时间:2020-09-18 18:27:10

标签: flutter

我正在尝试使用过滤器和图像包进行一些图像处理。我可以使其正常运行,但是它会挂起UI。

class ImageScreen extends StatefulWidget {
  static MaterialPageRoute route(String path) => MaterialPageRoute(
      builder: (context) => ImageScreen(
            imagePath: path,
          ));

  final String imagePath;

  const ImageScreen({Key key, this.imagePath}) : super(key: key);
  @override
  _ImageScreenState createState() => _ImageScreenState();
}

class _ImageScreenState extends State<ImageScreen> {
  int value = 0;
  Filter _filter;
  final _random = Random();
  _ImageScreenState();
  Widget _animatedWidget = const Center(child: CircularProgressIndicator());

  Future<Widget> _createImage(Filter filter) async {
    value++;
    _filter = filter;
    var bytes = await File(widget.imagePath).readAsBytes();
    var i = await  image.decodeImage( bytes );
    _filter.apply(i.getBytes(), i.width, i.height);
     return Image(key: ValueKey<int>(_random.nextInt(200)) , image: MemoryImage(image.encodeJpg(i)));
  }
  void _initiate(Filter filter) {
    debugPrint("initializing");
    _createImage(filter).then(
        (widget)=> setState(()=> _animatedWidget =widget));
    debugPrint("done");
  }

  @override
  void initState() {
    super.initState();
    _initiate(NoFilter());
  }
    @override
    Widget build(BuildContext context) {
      return Scaffold(body:
      Stack(
        children: [
          AnimatedSwitcher(child: _animatedWidget, duration: Duration(milliseconds: 200),),
          Align(
              alignment: Alignment.bottomCenter,
              child: Container(
                padding: EdgeInsets.only(top: 10, bottom: 10),
                color: Color.fromRGBO(200, 200, 200, 0.9),
                child: Row(
                  mainAxisSize: MainAxisSize.max,
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: [
                    FlatButton(
                      child: Text('Original'),
                      onPressed: () async  {
                       _initiate(NoFilter());
                      },
                    ),
                   
                    FlatButton(
                      child: Text('B&W'),
                      onPressed: ()  {
                          _initiate(MoonFilter());
                      },
                    ),
                    FlatButton(
                      child: Text('Dusty'),
                      onPressed: ()  {
                          _initiate(ReyesFilter());
                      },
                    )
                  ],
                ),
              )
          )
        ],
      ));
    }
  }

我想发生的事情是将处理从主线程中删除,然后看到一个不错的过渡。不幸的是,某些东西阻塞了主线程。 按钮陷入按下状态,然后在处理完成后,页面闪烁并显示新图像。

1 个答案:

答案 0 :(得分:0)

您必须将此功能设置为async

 Future<void> _initiate(Filter filter)async {
    debugPrint("initializing");
    _createImage(filter).then(
        (widget)=> setState(()=> _animatedWidget =widget));
    debugPrint("done");
  }

如果要调用此函数,则可以调用

 onPressed: () async  {
     await _initiate(NoFilter());
       },