程序在等待异步操作完成的过程中,非常有必要给予用户适当的反馈,这个时候就可以使用进度条。

进度条

CircularProgressIndicator

import 'package:flutter/material.dart';

class FormPage extends StatefulWidget {
  final Map arguments;
  const FormPage({
    super.key,
    required this.arguments,
  });

  @override
  State<FormPage> createState() => _FormPageState();
}

class _FormPageState extends State<FormPage> {
  bool flag = true;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    print(widget.arguments);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.arguments['title']),
        ),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: const [
            SizedBox(height: 10.0),
            CircularProgressIndicator(
              backgroundColor: Colors.grey,
              valueColor: AlwaysStoppedAnimation(Colors.red),
            ),
          ],
        ));
  }
}

LinearProgressIndicator()

import 'package:flutter/material.dart';

class FormPage extends StatefulWidget {
  final Map arguments;
  const FormPage({
    super.key,
    required this.arguments,
  });

  @override
  State<FormPage> createState() => _FormPageState();
}

class _FormPageState extends State<FormPage> {
  bool flag = true;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    print(widget.arguments);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.arguments['title']),
        ),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: const [
            LinearProgressIndicator(),
            SizedBox(height: 10.0),
            LinearProgressIndicator(
              backgroundColor: Colors.grey,
              valueColor: AlwaysStoppedAnimation(Colors.red),
            ),
            SizedBox(height: 10.0),
            LinearProgressIndicator(
              backgroundColor: Colors.grey,
              valueColor: AlwaysStoppedAnimation(Colors.red),
              value: 0.5,
            ),
          ],
        ));
  }
}

CupertinoActivityIndicator()

CircularProgressIndicator(
  backgroundColor: Colors.grey,
  valueColor: AlwaysStoppedAnimation(Colors.red),
),

Future异步

在其他语言,比如java、c++中, 同时要执行多个任务可以使用多线程来实现。而在Dart语言中没有线程和进程的概念 ,它是单线程+事件循环的设计模式,Dart和Flutter中要同时执行多个任务可以使用异步*来实现,Flutter中主要使用Future来实现异步操作 。

Future 返回值

Future 是一个泛型,其中T代表的是我们耗时操作返回的具体值,如Future 表示一个未来的字符串,Future表示一个未来的布尔值,如果不需要返回值,可以使用Future。

  • Future.value():返回一个指定值的Future

    Future<String> getStringNum() {
        return Future.value('你好Future');
    }
    
  • Future.delayed():返回一个延时执行的Future

    Future<String> getStringNum() {
        // return Future.value('你好Future');
        return Future.delayed(const Duration(seconds: 3), () {
          return '你好Future';
        });
    }
    
  • Future(() { ... return ... }) 返回异步的function

    Future<String> getStringNum() {
        return Future(() {
          var num = 0;
          for (var i = 0; i < 1000000000; i++) {
            num += i;
          }
          return 'result: $num';
        },);
      }
    

Flutter自带的Demo中有个计数器的功能,我们想的是执行计数器方法的时候让程序并行的去执行另一个统计的任务,这个时候就可以使用Future来完成。

import 'package:flutter/material.dart';

class FormPage extends StatefulWidget {
  final Map arguments;
  const FormPage({
    super.key,
    required this.arguments,
  });

  @override
  State<FormPage> createState() => _FormPageState();
}

class _FormPageState extends State<FormPage> {
  Future<String> getStringNum() {
    return Future(() {
      var num = 0;
      for (var i = 0; i < 1000000000; i++) {
        num += i;
      }
      return 'result: $num';
    },);
  }
  int countNum = 0;

  void _incrementCounter() async {
    getStringNum().then((value){
      print(value);
    });
    print('异步执行');
    setState(() {
      countNum++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.arguments['title']),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text(
                'You have pushed the button this many times:',
              ),
              Text(
                '$countNum',
                style: Theme.of(context).textTheme.headlineMedium,
              ),
            ],
          ),
        )
      );
  }
}

Future 处理异常

异常处理使我们在开发中特别需要注意的,正确的处理程序运行中的异常,能给用户带来更好的体验。

在future中可以使用catchError()或在then()方法中传入可选参数onError 来处理异常,可以使用whenComplete监听完成事件。

import 'package:flutter/material.dart';

class FormPage extends StatefulWidget {
  final Map arguments;
  const FormPage({
    super.key,
    required this.arguments,
  });

  @override
  State<FormPage> createState() => _FormPageState();
}

class _FormPageState extends State<FormPage> {
  Future<String> getStringNum() {
    // 抛出异常
    return Future.error(Exception('异步异常'));
  }
  int countNum = 0;

  void _incrementCounter() async {
    getStringNum().then((value){
      print(value);
    }).catchError((error){
      print(error);
    }).whenComplete(() {
      print('异步任务执行完成');
    });
    print('异步执行');
    setState(() {
      countNum++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.arguments['title']),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text(
                'You have pushed the button this many times:',
              ),
              Text(
                '$countNum',
                style: Theme.of(context).textTheme.headlineMedium,
              ),
            ],
          ),
        )
      );
  }
}

Future .then连缀来处理多个事务

import 'dart:math';

import 'package:flutter/material.dart';

class FormPage extends StatefulWidget {
  final Map arguments;
  const FormPage({
    super.key,
    required this.arguments,
  });

  @override
  State<FormPage> createState() => _FormPageState();
}

class _FormPageState extends State<FormPage> {
  Future<int> getStringNum() {
    // 抛出异常
    return Future(() {
      return 123;
    },);
  }
  int countNum = 0;

  void _incrementCounter() async {
    getStringNum().then((value){
      return value * 2;
    }).then((value){
      print(value);
    }).catchError((error){
      print(error);
    }).whenComplete((){
      print('执行完成');
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.arguments['title']),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text(
                'You have pushed the button this many times:',
              ),
              Text(
                '$countNum',
                style: Theme.of(context).textTheme.headlineMedium,
              ),
            ],
          ),
        )
      );
  }
}

async和await关键字来处理future

import 'dart:math';

import 'package:flutter/material.dart';

class FormPage extends StatefulWidget {
  final Map arguments;
  const FormPage({
    super.key,
    required this.arguments,
  });

  @override
  State<FormPage> createState() => _FormPageState();
}

class _FormPageState extends State<FormPage> {
  Future<int> getStringNum() {
    // 抛出异常
    return Future(() {
      return 123;
    },);
  }
  int countNum = 0;

  void _incrementCounter() async {
    var num = await getStringNum();
    print(num);
    print('执行了这里');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.arguments['title']),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text(
                'You have pushed the button this many times:',
              ),
              Text(
                '$countNum',
                style: Theme.of(context).textTheme.headlineMedium,
              ),
            ],
          ),
        )
      );
  }
}

处理async方法中的异常

对于async中的方法的异常,我们按以下方式进行处理:

import 'dart:math';

import 'package:flutter/material.dart';

class FormPage extends StatefulWidget {
  final Map arguments;
  const FormPage({
    super.key,
    required this.arguments,
  });

  @override
  State<FormPage> createState() => _FormPageState();
}

class _FormPageState extends State<FormPage> {
  Future<int> getStringNum() {
    // 抛出异常
    return Future.error(Exception("this is errot"));
  }
  int countNum = 0;

  void _incrementCounter() async {
    var result;
    try {
      result = await getStringNum();
    } catch (e) {
      print(e);
      result = 0;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.arguments['title']),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text(
                'You have pushed the button this many times:',
              ),
              Text(
                '$countNum',
                style: Theme.of(context).textTheme.headlineMedium,
              ),
            ],
          ),
        )
      );
  }
}

results matching ""

    No results matching ""