I have a loop that prints "hello world" 100 times. 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..
how to show 'for' loop progress Indicator in flutter
1.6k Views Asked by FTF Studio At
3
There are 3 best solutions below
0
On
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
}
}
}
0
On
Here Direct Setstate not work because for loop execute as soon as possible.So we add 100 millisecond time delay for visual progress
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
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.
SampleCode Dart pad Live code
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;
});
}
}

Like @pskink mentioned in the comments, a
LinearProgressIndicatororCircularProgressIndicatorshould do the trick. 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. That could look a bit like: