openplanning

Hướng dẫn và ví dụ Flutter CircularProgressIndicator

  1. CircularProgressIndicator
  2. Example: Indeterminate
  3. Example: Determinate
  4. backgroundColor
  5. value
  6. valueColor
  7. strokeWidth
  8. semanticsLabel
  9. semanticsValue

1. CircularProgressIndicator

CircularProgressIndicator là một lớp con của ProgressIndicator, nó tạo ra một chỉ báo tiến trình (progress indicator) dạng hình tròn.
CircularProgressIndicator được chia làm 2 loại:
Determinate
Determinate (Xác định): Là một chỉ báo tiến trình có thể hiển thị cho người dùng phần trăm công việc mà nó đã hoàn thành dựa trên giá trị của property value (Giá trị nằm trong khoảng 0 tới 1)
Indeterminate
Indeterminate (Không xác định): Là một chỉ báo tiến trình không xác định được phần trăm công việc đã hoàn thành và không thể xác định được thời điểm kết thúc.
CircularProgressIndicator Constructor:
CircularProgressIndicator constructor
const CircularProgressIndicator(
    {Key key,
    double value,
    Color backgroundColor,
    Animation<Color> valueColor,
    double strokeWidth: 4.0,
    String semanticsLabel,
    String semanticsValue}
)

2. Example: Indeterminate

Chúng ta sẽ bắt đầu với một ví dụ đơn giản nhất, một CircularProgressIndicator mô phỏng một tiến trình đang hoạt động nhưng không biết rõ phần trăm công việc đã được hoàn thành và không biết thời điểm kết thúc.
main.dart (ex 1)
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'o7planning.org',
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter CircularProgressIndicator Example'),
      ),
      body: Center(
        child:  CircularProgressIndicator(
          backgroundColor: Colors.cyanAccent,
          valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),
        ),
      ),
    );
  }
}
Theo mặc định CircularProgressIndicator có bán kính khá nhỏ, nếu bạn muốn tuỳ biến kích thước hãy đặt nó trong một SizedBox.
SizedBox(
  width: 200,
  height: 200,
  child: CircularProgressIndicator(
    strokeWidth: 10,
    backgroundColor: Colors.cyanAccent,
    valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),
  ),
)
Tham số valueColor được sử dụng để chỉ định một hiệu ứng hoạt hình mầu sắc cho tiến trình (progress) của CircularProgressIndicator, chẳng hạn:
valueColor: new AlwaysStoppedAnimation<Color>(Colors.red)
AlwaysStoppedAnimation<Color> sẽ luôn luôn ngừng hiệu ứng hoạt hình đối với CircularProgressIndicator nếu tham số value là một giá trị cụ thể khác null.
SizedBox(
  width: 200,
  height: 200,
  child: CircularProgressIndicator(
    value: 0.3,
    backgroundColor: Colors.cyanAccent,
    valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),
  ),
)
Dựa trên các quy tắc đặc điểm nói trên của tham số valuevalueColor bạn có thể điều khiển hành vi của CircularProgressIndicator, hãy xem một ví dụ:
main.dart (ex 1d)
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'o7planning.org',
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {

  @override
  State<StatefulWidget> createState() {
    return _HomePageState();
  }
}

class _HomePageState extends State<HomePage> {

  bool _working = false;

  void startWorking() async {
    this.setState(() {
      this._working = true;
    });
  }

  void finishWorking() {
    this.setState(() {
      this._working = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter CircularProgressIndicator Example'),
      ),
      body: Center(
          child:  Column (
              mainAxisAlignment: MainAxisAlignment.center,
              children:  [
                SizedBox(
                  width: 100,
                  height: 100,
                  child: CircularProgressIndicator(
                    value: this._working? null: 1,
                    backgroundColor: Colors.cyanAccent,
                    valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),
                  ),
                ),
                ElevatedButton(
                    child: Text("Start"),
                    onPressed: this._working? null: () {
                      this.startWorking();
                    }
                ),
                ElevatedButton(
                    child: Text("Finish"),
                    onPressed: !this._working? null: () {
                      this.finishWorking();
                    }
                )
              ]
          )
      ),
    );
  }
}

3. Example: Determinate

Tiếp theo là một ví dụ sử dụng CircularProgressIndicator để biểu thị một tiến trình với thông tin về phần trăm công việc đã hoàn thành. Tham số value có giá trị từ 0 đến 1.
main.dart (ex 2)
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'o7planning.org',
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {

  @override
  State<StatefulWidget> createState() {
    return _HomePageState();
  }
}

class _HomePageState extends State<HomePage> {

  double _value = 0;
  bool _working = false;

  void startWorking()  async {
    this.setState(() {
      this._working = true;
      this._value = 0;
    });
    for(int i = 0; i< 10; i++) {
      if(!this._working)  {
         break;
      }
      await Future.delayed(Duration(seconds: 1));
      this.setState(() {
        this._value += 0.1;
      });
    }
    this.setState(() {
      this._working = false;
    });
  }

  void stopWorking() {
    this.setState(() {
      this._working = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter CircularProgressIndicator Example'),
      ),
      body: Center(
          child:  Column (
              mainAxisAlignment: MainAxisAlignment.center,
              children:  [
                SizedBox(
                  width: 100,
                  height: 100,
                  child: CircularProgressIndicator(
                    value: this._value,
                    backgroundColor: Colors.cyanAccent,
                    valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),
                  ),
                ),
                Text(
                  "Percent: " + (this._value * 100).round().toString()+ "%",
                  style: TextStyle(fontSize: 20),
                ),
                ElevatedButton(
                    child: Text("Start"),
                    onPressed: this._working? null: () {
                      this.startWorking();
                    }
                ),
                ElevatedButton(
                    child: Text("Stop"),
                    onPressed: !this._working? null: () {
                      this.stopWorking();
                    }
                )
              ]
          )
      ),
    );
  }
}

4. backgroundColor

backgroundColor được sử dụng để sét đặt mầu nền cho CircularProgressIndicator.
Color backgroundColor

5. value

double value

6. valueColor

valueColor được sử dụng để chỉ định một hiệu ứng hoạt hình mầu sắc cho tiến trình (progress).
Animation<Color> valueColor
Ví dụ:
CircularProgressIndicator(
  strokeWidth: 20,
  backgroundColor: Colors.cyanAccent,
  valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),
)
  • Hướng dẫn và ví dụ Flutter Animation

7. strokeWidth

strokeWidth là chiều rộng của nét vẽ đường tròn, giá trị mặc định là 4 pixel.
double strokeWidth: 4.0

8. semanticsLabel

semanticsLabel được sử dụng để mô tả mục đích sử dụng của CircularProgressIndicator, nó hoàn toàn ẩn trên giao diện và có ý nghĩa với các thiết bị đọc màn hình (Screen reader), chẳng hạn các thiết bị đọc màn hình dành cho người mù.
String semanticsLabel

9. semanticsValue

semanticsValue hoàn toàn ẩn trên màn hình, mục đích của nó là cung cấp thông tin về tiến trình hiện tại cho các thiết bị đọc màn hình.
Theo mặc định giá trị của semanticsValue là phần trăm công việc đã hoàn thành, chẳng hạn giá trị của property value0.3 thì semanticsValue sẽ là "30%".
String semanticsValue
Ví dụ:
CircularProgressIndicator(
  value: this._value,
  backgroundColor: Colors.cyanAccent,
  valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),
  semanticsLabel: "Downloading file abc.mp3",
  semanticsValue: "Percent " + (this._value * 100).toString() + "%",
)

Các hướng dẫn lập trình Flutter

Show More