简体   繁体   English

如何在 flutter 中显示“for”循环进度指示器

[英]how to show 'for' loop progress Indicator in flutter

I have a loop that prints "hello world" 100 times.我有一个打印“hello world”100 次的循环。 so what i want is to show progress Indicator which shows the loop progress.. for example: if the loop printed 50 time from total 100 time the progress Indicator should be at 50 percent..所以我想要的是显示进度指示器,它显示循环进度..例如:如果循环打印总计 100 次中的 50 次,则进度指示器应为 50%..

Like @pskink mentioned in the comments, a LinearProgressIndicator or CircularProgressIndicator should do the trick.就像评论中提到的 @pskink 一样, LinearProgressIndicatorCircularProgressIndicator应该可以解决问题。 Do go into a bit more detail, you can store the progress after each iteration (or every so many iterations depending on your needs), and if you use your widget's state for it, a rebuild should automatically trigger and rebuild the progress indicator with the new value each time.做 go 更详细一点,你可以在每次迭代后存储进度(或者根据你的需要每隔这么多次迭代),如果你使用你的小部件的 state ,重建应该自动触发并重建进度指示器每次都有新的价值。 That could look a bit like:这看起来有点像:

// inside the State
double progress = 0.0;

doTheLoop() {
  for (int i = 0; i < 100; i++) {
    print('Hello world');
    setState(() => progress = i/100);
  }
}

build(BuildContext context) {
  return Column(children: [
    Container(
      // the progress indicator updates when the progress variable in the state updates, since a rebuild is triggered
      child: LinearProgressIndicator(
        progress: progress,
      );
    ),
    
    // press the button to start the loop
    ElevatedButton(
      child: Text('Start loop'),
      onPressed: doTheLoop,
    ),
  ],),
}

Here Direct Setstate not work because for loop execute as soon as possible.So we add 100 millisecond time delay for visual progress这里 Direct Setstate不起作用,因为 for 循环会尽快执行。所以我们为视觉进度添加 100 毫秒的时间延迟

await Future.delayed(Duration(milliseconds: 100));

Linewar Widget线性微件

LinearProgressIndicator(
                minHeight: 25,
                value: _value,
                color: _color,
                semanticsValue: (_value * 100).toString(),
                semanticsLabel: (_value * 100).toString(),
              )

while Press loopbutton同时按下循环按钮

  Future<void> loop() async {
    for (int i = 0; i <= 100; i++) {

      await Future.delayed(Duration(milliseconds: 100));
      var element = i;
      print(element);
      setState(() {
        _value = element / 100;
        print(_value);
      });
      if (element < 5 && element > 0)
        _color = Colors.red;
      else if (element < 25 && element > 5)
        _color = Colors.cyan;
      else if (element < 50 && element > 25)
        _color = Colors.lightGreenAccent;
      else if (element < 75 && element > 50)
        _color = Colors.lightGreen;
      else if (element < 100 && element > 75) _color = Colors.green;
    }
  }

在此处输入图像描述

Without Streamcontroller dartpad没有 Streamcontroller飞镖板

import 'dart:async';

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: "/",
      routes: {
        "/": (context) => Home(),
      },
      title: _title,
      // home: ,
    );
  }
}

class Home extends StatelessWidget {
  const Home({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("title")),
      body: const Center(
        child: MyStatelessWidget(),
      ),
    );
  }
}

var _color = Colors.black;
var _value = 0.0;

class MyStatelessWidget extends StatefulWidget {
  const MyStatelessWidget({Key? key}) : super(key: key);

  @override
  State<MyStatelessWidget> createState() => _MyStatelessWidgetState();
}

class _MyStatelessWidgetState extends State<MyStatelessWidget> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: <Widget>[
          Container(
            padding: EdgeInsets.all(8),
            child: Stack(
              children: [
                Positioned(
                  child: Container(
                    height: 100,
                    width: 100,
                    child: CircularProgressIndicator(
                      strokeWidth: 4,
                      value: _value,
                      color: _color,
                    ),
                  ),
                  top: 0,
                  left: 0,
                  right: 0,
                  bottom: 0,
                ),
                Positioned(
                  child: Text(
                    (_value * 100).toStringAsFixed(1),
                    style: TextStyle(fontSize: 15),
                  ),
                  top: 25,
                  left: 10,
                ),
              ],
            ),
            height: 75,
            width: 75,
          ),
          Container(
              padding: EdgeInsets.all(8),
              child: LinearProgressIndicator(
                minHeight: 25,
                value: _value,
                color: _color,
                semanticsValue: (_value * 100).toString(),
                semanticsLabel: (_value * 100).toString(),
              )),
          Text(
            (_value * 100).toStringAsFixed(1),
            style: TextStyle(fontSize: 25),
          ),
          Row(
            children: [
              Expanded(
                child: IconButton(
                  onPressed: () {
                    loop();
                  },
                  icon: Icon(
                    Icons.not_started_outlined,
                    size: 45,
                  ),
                ),
              ),
              Expanded(
                child: IconButton(
                  onPressed: () {},
                  icon: Icon(Icons.stop, size: 45),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  Future<void> loop() async {
    for (int i = 0; i <= 100; i++) {
      // if (!stream.isClosed) stream.sink.addStream(Stream.value(i));
      await Future.delayed(Duration(milliseconds: 100));
      var element = i;
      print(element);
      setState(() {
        _value = element / 100;
        print(_value);
      });
      if (element < 5 && element > 0)
        _color = Colors.red;
      else if (element < 25 && element > 5)
        _color = Colors.cyan;
      else if (element < 50 && element > 25)
        _color = Colors.lightGreenAccent;
      else if (element < 75 && element > 50)
        _color = Colors.lightGreen;
      else if (element < 100 && element > 75) _color = Colors.green;
    }
  }

  @override
  void initState() {}
}

This Sample.Here use streamcontroller .so using stream controller mange the progress like pause or stop the progress.此 Sample.Here 使用streamcontroller .so 使用 stream controller 管理暂停或停止进度等进度。

SampleCode Dart pad Live code SampleCode Dart pad活码

import 'dart:async';

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: "/",
      routes: {
        "/": (context) => Home(),
      },
      title: _title,
      // home: ,
    );
  }
}

class Home extends StatelessWidget {
  const Home({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("title")),
      body: const Center(
        child: MyStatelessWidget(),
      ),
    );
  }
}

var _color = Colors.black;
var _value = 0.0;

class MyStatelessWidget extends StatefulWidget {
  const MyStatelessWidget({Key? key}) : super(key: key);

  @override
  State<MyStatelessWidget> createState() => _MyStatelessWidgetState();
}

class _MyStatelessWidgetState extends State<MyStatelessWidget> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: <Widget>[
          Container(
            padding: EdgeInsets.all(8),
            child: Stack(
              children: [
                Positioned(
                  child: Container(
                    height: 100,
                    width: 100,
                    child: CircularProgressIndicator(
                      strokeWidth: 4,
                      value: _value,
                      color: _color,
                    ),
                  ),
                  top: 0,
                  left: 0,
                  right: 0,
                  bottom: 0,
                ),
                Positioned(
                  child: Text(
                    (_value * 100).toStringAsFixed(1),
                    style: TextStyle(fontSize: 15),
                  ),
                  top: 25,
                  left: 10,
                ),
              ],
            ),
            height: 75,
            width: 75,
          ),
          Container(
              padding: EdgeInsets.all(8),
              child: LinearProgressIndicator(
                minHeight: 25,
                value: _value,
                color: _color,
                semanticsValue: (_value * 100).toString(),
                semanticsLabel: (_value * 100).toString(),
              )),
          Text(
            (_value * 100).toStringAsFixed(1),
            style: TextStyle(fontSize: 25),
          ),
          Row(
            children: [
              Expanded(
                child: IconButton(
                  onPressed: () {
                    loop();
                  },
                  icon: Icon(
                    Icons.not_started_outlined,
                    size: 45,
                  ),
                ),
              ),
              Expanded(
                child: IconButton(
                  onPressed: () {
                    stream.close();
                  },
                  icon: Icon(Icons.stop, size: 45),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  Future<void> loop() async {
    for (int i = 0; i <= 100; i++) {
      if (!stream.isClosed) stream.sink.addStream(Stream.value(i));
      await Future.delayed(Duration(milliseconds: 100));
    }
    // List.generate(100, (index) => index + 1).forEach((element) async {
    //   if (!stream.isClosed) stream.sink.addStream(Stream.value(element));
    //   await Future.delayed(Duration(seconds: 1));
    // });
  }

  // late StreamController<int> stream;
  StreamController<int> stream = StreamController();

  @override
  void initState() {
    stream.stream.listen((element) {
      print(element);
      setState(() {
        _value = element / 100;
        print(_value);
      });
      if (element < 5 && element > 0)
        _color = Colors.red;
      else if (element < 25 && element > 5)
        _color = Colors.cyan;
      else if (element < 50 && element > 25)
        _color = Colors.lightGreenAccent;
      else if (element < 75 && element > 50)
        _color = Colors.lightGreen;
      else if (element < 100 && element > 75) _color = Colors.green;
    });
  }
}

please try this请试试这个

 class testwidget extends StatefulWidget {
  const testwidget({Key? key}) : super(key: key);

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

class _test extends State<testwidget> {

  StreamController loopValueStram=new StreamController();
  var loopProgress=0.0;
  static const  max=100;


  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    loopValueStram.stream.listen((event) {
      setState(() {
        loopProgress=event;
      });
    });
  }

  @override
  void dispose() {
    super.dispose();
  }



  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('test'),
        ),
        body: Center(
          child:Column(
            children: [
              RaisedButton(
                onPressed: (){
                  loop();
                },
                child: Text("Start loop ${(loopProgress*100).toInt()}%"),
              ),
              SizedBox(height: 10,),
              Padding(padding: EdgeInsets.all(20),
                child: Visibility(
                    visible:loopProgress>0,
                    child: LinearProgressIndicator(
                      value: loopProgress.toDouble(),
                      semanticsLabel: "Progress",
                      minHeight: 40,
                    )),
              )
            ],
          )
        )
    );
  }

  Future<void> loop() async {
    for(int i=0;i<=100;i++){
      loopValueStram.sink.add(i/100);
      await Future.delayed(Duration(seconds: 1));// this line is to slowdown itération so we can see linear pregression well
    }
  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM