Progress bar(Thanh tiến trình) là một phần tử điều khiển đồ họa được sử dụng để hiển thị tiến trình của một tác vụ như tải xuống, tải lên, cài đặt, truyền tệp, v.v. Trong phần này, chúng ta sẽ hiểu cách hiển thị progress bar trong một ứng dụng rung.

Flutter có thể hiển thị progress bar với sự trợ giúp của hai widget con, được đưa ra dưới đây:

  1. LinearProgressIndicator
  2. RoundProgressIndicator

Hãy để chúng ta hiểu nó một cách chi tiết.

1. LinearProgressIndicator

Progress bar tuyến tính được sử dụng để hiển thị tiến trình của nhiệm vụ theo đường ngang .

Flutter chủ yếu cung cấp hai loại chỉ báo tiến trình tuyến tính:

Determinate: Thanh tiến độ xác định cho biết lượng tiến độ thực tế tại mỗi thời điểm trong quá trình thực hiện nhiệm vụ. Giá trị của nó sẽ tăng đơn điệu từ 0,0 lên 1,0 để hiển thị số lượng nhiệm vụ đã hoàn thành tại thời điểm đó. Chúng ta cần sử dụng giá trị khác rỗng từ 0,0 đến 1,0 để tạo chỉ báo tiến trình xác định.

Indeterminate: progress bar không xác định không cho biết số lượng tiến độ hoàn thành nhiệm vụ. Nó có nghĩa là chúng ta không biết khi nào nhiệm vụ kết thúc. Nó tạo ra sự tiến bộ mà không cho biết mức độ tiến bộ còn lại . Chúng ta có thể tạo chỉ báo tiến trình không xác định bằng cách sử dụng giá trị null .

1.1 Properties

Sau đây là các thuộc tính phổ biến nhất của chỉ báo tiến trình tuyến tính:

double value: Nó được sử dụng để chỉ định giá trị không rỗng trong khoảng từ 0,0 đến 1,0, đại diện cho việc hoàn thành tiến độ tác vụ.

Color backgroundColor: Nó được sử dụng để chỉ định màu nền của widget.

Animation <Color> valueColor: Nó được sử dụng để chỉ định màu của chỉ báo tiến trình làm giá trị hoạt ảnh.

1.2 Thí dụ

Đoạn code sau giải thích việc sử dụng progress bar tuyến tính không xác định hiển thị quá trình tải xuống mà chúng ta không biết khi nào sẽ kết thúc. Một nút nổi được sử dụng để thay đổi trạng thái từ không tải xuống thành tải xuống. Khi không có tải xuống, nó sẽ hiển thị một văn bản; nếu không, nó sẽ hiển thị chỉ báo tiến trình:

import 'package:flutter/material.dart';  
  
void main() => runApp(MyApp());  
  
class MyApp extends StatelessWidget {  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      home: LinearProgressIndicatorApp(),  
    );  
  }  
}  
  
class LinearProgressIndicatorApp extends StatefulWidget {  
  @override  
  State<StatefulWidget> createState() {  
    return LinearProgressIndicatorAppState();  
  }  
}  
  
class LinearProgressIndicatorAppState extends State<LinearProgressIndicatorApp> {  
  bool _loading;  
  
  @override  
  void initState() {  
    super.initState();  
    _loading = false;  
  }  
  
  @override  
  Widget build(BuildContext context) {  
    return Scaffold(  
      appBar: AppBar(  
        title: Text("Flutter Linear Progress Bar"),  
      ),  
      body: Center(  
        child: Container(  
          padding: EdgeInsets.all(12.0),  
          child: _loading ? LinearProgressIndicator() : Text(  
              "Press button for downloading",  
              style: TextStyle(fontSize: 25)),  
        ),  
      ),  
      floatingActionButton: FloatingActionButton(  
        onPressed: () {  
          setState(() {  
            _loading = !_loading;  
          });  
        },  
        tooltip: 'Download',  
        child: Icon(Icons.cloud_download),  
      ),  
    );  
  }  
}  

Đầu ra:

Bây giờ, hãy chạy ứng dụng trong IDE của bạn. Chúng ta có thể thấy giao diện người dùng của màn hình như ảnh chụp màn hình bên dưới.

Khi chúng ta nhấn nút nổi, nó sẽ thay đổi trạng thái từ không tải xuống thành tải xuống và hiển thị chỉ báo tiến trình như ảnh chụp màn hình bên dưới:

Đôi khi chúng ta muốn tạo một progress bar xác định nghĩa là chúng ta sẽ chỉ ra rằng sẽ mất bao lâu để hoàn thành nhiệm vụ. Trong trường hợp đó, chúng ta có thể mô phỏng quá trình tải xuống sẽ mất thời gian để hoàn thành tác vụ và cập nhật giá trị của LinearProgressIndicator như sau:

import 'dart:async';  
import 'package:flutter/material.dart';  
  
void main() => runApp(MyApp());  
  
class MyApp extends StatelessWidget {  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      home: LinearProgressIndicatorApp(),  
    );  
  }  
}  
  
class LinearProgressIndicatorApp extends StatefulWidget {  
  @override  
  State<StatefulWidget> createState() {  
    return LinearProgressIndicatorAppState();  
  }  
}  
  
class LinearProgressIndicatorAppState extends State<LinearProgressIndicatorApp> {  
  bool _loading;  
  double _progressValue;  
  
  @override  
  void initState() {  
    super.initState();  
    _loading = false;  
    _progressValue = 0.0;  
  }  
  @override  
  Widget build(BuildContext context) {  
    return Scaffold(  
      appBar: AppBar(  
        title: Text("Flutter Linear Progress Bar"),  
      ),  
      body: Center(  
        child: Container(  
          padding: EdgeInsets.all(12.0),  
          child: _loading  
              ? Column(  
            mainAxisAlignment: MainAxisAlignment.center,  
            children: <Widget>[  
              LinearProgressIndicator(  
                backgroundColor: Colors.cyanAccent,  
                valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),  
                value: _progressValue,  
              ),  
              Text('${(_progressValue * 100).round()}%'),  
            ],  
          )  
              : Text("Press button for downloading", style: TextStyle(fontSize: 25)),  
        ),  
      ),  
      floatingActionButton: FloatingActionButton(  
        onPressed: () {  
          setState(() {  
            _loading = !_loading;  
            _updateProgress();  
          });  
        },  
        tooltip: 'Download',  
        child: Icon(Icons.cloud_download),  
      ),  
    );  
  }  
  // this function updates the progress value  
  void _updateProgress() {  
    const oneSec = const Duration(seconds: 1);  
    new Timer.periodic(oneSec, (Timer t) {  
      setState(() {  
        _progressValue += 0.1;  
        // we "finish" downloading here  
        if (_progressValue.toStringAsFixed(1) == '1.0') {  
          _loading = false;  
          t.cancel();  
          return;  
        }  
      });  
    });  
  }  
}

Đầu ra:

Bây giờ, hãy chạy ứng dụng trong IDE của bạn. Khi chúng ta nhấn nút, nó sẽ thay đổi trạng thái từ không tải xuống thành tải xuống và hiển thị bao nhiêu tiến trình đã hoàn thành tại thời điểm đó như ảnh chụp màn hình bên dưới:

2. CircularProgressIndicator

Nó là một widget, quay để chỉ ra quá trình chờ đợi trong ứng dụng của bạn. Nó hiển thị tiến trình của một nhiệm vụ trong một hình tròn . Nó cũng hiển thị progress bar theo hai cách: Xác định và Không xác định.

Một progress bar xác định được sử dụng khi chúng ta muốn thể hiện sự tiến bộ của công việc đang diễn ra như tỷ lệ tải hoặc upload file, vv Chúng ta có thể hiển thị các tiến trình bằng cách xác định giá trị giữa 0.0 và 1.0.

Một progress bar không xác định được sử dụng khi chúng ta không muốn biết tỷ lệ phần trăm của một quá trình liên tục. Theo mặc định, CircularProgressIndicator hiển thị progress bar không xác định.

2.1 Thí dụ

Trong ví dụ dưới đây, chúng ta sẽ thấy chỉ báo tiến độ vòng tròn ở chế độ không xác định không hiển thị tiến độ của bất kỳ nhiệm vụ nào. Nó hiển thị các vòng tròn liên tục, điều này cho biết rằng một cái gì đó đang được hoàn thiện và chúng ta phải đợi nó hoàn thành. Đối với điều này, không cần phải chỉ định bất kỳ giá trị nào cho hàm tạo CircularProgressIndicator(). Xem đoạn code sau:

import 'package:flutter/material.dart';  
  
void main() => runApp(MyApp());  
  
class MyApp extends StatelessWidget {  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      home: Scaffold(  
        appBar: AppBar(  
          title: Text('Flutter Progress Bar Example'),  
        ),  
        body: Center(  
            child: CircularProgressIndicatorApp()  
        ),  
      ),  
    );  
  }  
}  
  
/// This is the stateless widget that the main application instantiates.  
class CircularProgressIndicatorApp extends StatelessWidget {  
  @override  
  Widget build(BuildContext context) {  
    return CircularProgressIndicator(  
      backgroundColor: Colors.red,  
      strokeWidth: 8,);  
  }  
}  

Đầu ra:

Bây giờ, hãy chạy ứng dụng trong IDE của bạn. Chúng ta sẽ thấy đầu ra của chỉ báo tiến trình vòng tròn flutter như ảnh chụp màn hình bên dưới:

Đôi khi bạn muốn tạo một progress bar vòng tròn xác định để cho biết sẽ mất bao nhiêu thời gian để hoàn thành nhiệm vụ. Trong trường hợp đó, chúng ta có thể mô phỏng quá trình tải xuống sẽ mất thời gian để hoàn thành tác vụ và cập nhật giá trị của CircularProgressIndicator như sau:

import 'dart:async';  
import 'package:flutter/material.dart';  
  
void main() => runApp(MyApp());  
  
class MyApp extends StatelessWidget {  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      home: CircularProgressIndicatorApp(),  
    );  
  }  
}  
  
class CircularProgressIndicatorApp extends StatefulWidget {  
  @override  
  State<StatefulWidget> createState() {  
    return CircularProgressIndicatorAppState();  
  }  
}  
  
class CircularProgressIndicatorAppState extends State<CircularProgressIndicatorApp>{  
  bool _loading;  
  double _progressValue;  
  
  @override  
  void initState() {  
    super.initState();  
    _loading = false;  
    _progressValue = 0.0;  
  }  
  @override  
  Widget build(BuildContext context) {  
    return Scaffold(  
      appBar: AppBar(  
        title: Text("Flutter Circular Progress Bar"),  
      ),  
      body: Center(  
        child: Container(  
          padding: EdgeInsets.all(14.0),  
          child: _loading  
              ? Column(  
            mainAxisAlignment: MainAxisAlignment.center,  
            children: <Widget>[  
              CircularProgressIndicator(  
                strokeWidth: 10,  
                backgroundColor: Colors.yellow,  
                valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),  
                value: _progressValue,  
              ),  
              Text('${(_progressValue * 100).round()}%'),  
            ],  
          )  
              : Text("Press button for downloading", style: TextStyle(fontSize: 25)),  
        ),  
      ),  
      floatingActionButton: FloatingActionButton(  
        onPressed: () {  
          setState(() {  
            _loading = !_loading;  
            _updateProgress();  
          });  
        },  
        child: Icon(Icons.cloud_download),  
      ),  
    );  
  }  
  // this function updates the progress value  
  void _updateProgress() {  
    const oneSec = const Duration(seconds: 1);  
    new Timer.periodic(oneSec, (Timer t) {  
      setState(() {  
        _progressValue += 0.2;  
        // we "finish" downloading here  
        if (_progressValue.toStringAsFixed(1) == '1.0') {  
          _loading = false;  
          t.cancel();  
          return;  
        }  
      });  
    });  
  }  
}  

Đầu ra:

Bây giờ, hãy chạy ứng dụng trong IDE của bạn. Khi chúng ta nhấn nút, nó sẽ hiển thị bao nhiêu tiến độ đã hoàn thành tại thời điểm đó như ảnh chụp màn hình bên dưới:

Cài ứng dụng cafedev để dễ dàng cập nhật tin và học lập trình mọi lúc mọi nơi tại đây.

Tài liệu từ cafedev:

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!