openplanning

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

  1. LinearProgressIndicator
  2. Example: Indeterminate
  3. Example: Determinate
  4. Example: Vertical Progress
  5. backgroundColor
  6. value
  7. valueColor
  8. minHeight
  9. semanticsLabel
  10. semanticsValue

1. LinearProgressIndicator

LinearProgressIndicator là một lớp con của ProgressIndicator, nó tạo ra một thanh chỉ báo tiến trình (progress bar indicator) nằm ngang, tuy nhiên bạn cũng có thể tạo ra thanh chỉ báo tiến trình thẳng đứng nếu đặt nó bên trong một RotatedBox quay 90 độ.
LinearProgressIndicator đượ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.
LinearProgressIndicator Constructor:
LinearProgressIndicator constructor
const LinearProgressIndicator(
    {Key key,
    double value,
    Color backgroundColor,
    Animation<Color> valueColor,
    double minHeight,
    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 LinearProgressIndicator 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 LinearProgressIndicator Example'),
      ),
      body: Center(
        child:  LinearProgressIndicator(
          backgroundColor: Colors.cyan[100],
          valueColor: new AlwaysStoppedAnimation<Color>(Colors.green),
        ),
      ),
    );
  }
}
Theo mặc định LinearProgressIndicator có kích thước 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: 250,
  height: 20,
  child: LinearProgressIndicator(
    backgroundColor: Colors.cyan[100],
    valueColor: new AlwaysStoppedAnimation<Color>(Colors.green),
  ),
)
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 LinearProgressIndicator, 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 LinearProgressIndicator nếu tham số value là một giá trị cụ thể khác null.
SizedBox(
  width: 250,
  height: 20,
  child: LinearProgressIndicator(
    value: 0.3,
    backgroundColor: Colors.cyan[100],
    valueColor: new AlwaysStoppedAnimation<Color>(Colors.green),
  ),
)
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 LinearProgressIndicator, 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 LinearProgressIndicator Example'),
      ),
      body: Center(
          child:  Column (
              mainAxisAlignment: MainAxisAlignment.center,
              children:  [
                SizedBox(
                  width: 250,
                  height: 20,
                  child: LinearProgressIndicator(
                    value: this._working? null: 1,
                    backgroundColor: Colors.cyan[100],
                    valueColor: new AlwaysStoppedAnimation<Color>(Colors.green),
                  ),
                ),
                SizedBox(width:10, height:10),
                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 LinearProgressIndicator để 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 LinearProgressIndicator Example'),
      ),
      body: Center(
          child:  Column (
              mainAxisAlignment: MainAxisAlignment.center,
              children:  [
                SizedBox(
                  width: 250,
                  height: 20,
                  child: LinearProgressIndicator(
                    value: this._value,
                    backgroundColor: Colors.cyan[100],
                    valueColor: new AlwaysStoppedAnimation<Color>(Colors.green),
                  ),
                ),
                SizedBox(width:10, height: 10),
                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. Example: Vertical Progress

Về cơ bản LinearProgressIndicator không hỗ trợ chiều thẳng đứng, tuy nhiên nếu bạn muốn có một thanh tiến trình thẳng đứng bạn có thể đặt nó trong một RotatedBox với góc quay 90 độ.
Ví dụ:
RotatedBox(
    quarterTurns: -1,
    child: SizedBox(
        width: 250,
        height: 25,
        child : LinearProgressIndicator(
          backgroundColor: Colors.cyan[100],
          valueColor: new AlwaysStoppedAnimation<Color>(Colors.green),
        )
    )
)
  • Tham số quarterTurns = 1, nghĩa là quay xuôi chiều kim đồng hồ 90 độ.
  • Ngược lại nếu quarterTurns = -1, nghĩa là quay ngược chiều kim đồng hồ 90 độ.

5. backgroundColor

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

6. value

double value

7. 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ụ:
LinearProgressIndicator(
  backgroundColor: Colors.cyanAccent,
  valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),
)
  • Hướng dẫn và ví dụ Flutter Animation

8. minHeight

minHeight được sử dụng để sét đặt chiều cao nhỏ nhất cho LinearProgressIndicator.
double minHeight

9. semanticsLabel

semanticsLabel được sử dụng để mô tả mục đích sử dụng của LinearProgressIndicator, 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

10. 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ụ:
LinearProgressIndicator(
  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