Flutter父级进度条管理插件parent_progress的使用

发布于 1周前 作者 phonegap100 来自 Flutter

Flutter父级进度条管理插件parent_progress的使用

本包为您的Flutter进度指示器提供了解决方案。它通过三个主要类:FictionalProgressRationalProgressParentProgress 来管理和跟踪跨多个任务的进度。这些类允许每个子进度独立跟踪并贡献到一个聚合的父进度,使用 ValueNotifier<int> 实现动态更新和UI集成。适用于在模块化应用中进行复杂的进度管理。

特性

  • FictionalProgress

    • 模拟基于预定义大小的进度。适用于实际数据处理细节被抽象化的场景。
    • 当精确的数据或任务完成指标不可用时,用于表示进度。
  • RationalProgress

    • 基于真实数据处理或任务完成情况来跟踪实际进度。适合需要精确跟踪已完成与总工作量的应用程序。
  • ParentProgress

    • 使用加权系统从多个子进度中聚合进度。提供对各种组件或模块整体进度的全面概览。

使用方法

FictionalProgress

FictionalProgress 用于根据预定义的大小模拟进度。当需要展示进度但实际指标不直接可测量时非常有用。

List<int> sizes = [10, 20, 30]; // 每个数字代表任务的一个段
FictionalProgress progress = FictionalProgress(sizes);

// 开始进度模拟
progress.finishProgressUpToIndexLevel(
    processIndexLevel: 1, 
    processingLenghtPerS: 5, 
    updateIntervalMs: 100);

RationalProgress

使用 RationalProgress 跟踪实时进度的可测量任务或数据处理活动。适用于需要精确进度跟踪的应用程序。

RationalProgress progress = RationalProgress(totalWork: 100);

// 更新进度作为任务进展
progress.currentWorkDone(50); // 已完成50%的工作

// 获取当前进度
print("Current progress: ${progress.getCurrentPercentage}%");

ParentProgress

ParentProgress 允许您从多个进度中聚合进度。这在不同模块或组件独立报告进度的复杂应用程序中非常有用。

// 创建个体进度
FictionalProgress child1 = FictionalProgress([50, 50]);
RationalProgress child2 = RationalProgress(totalWork: 100);

// 子进度及其对应的权重列表
List<ChildProgress> children = [child1, child2];
List<int> weights = [1, 2];

// 创建父进度
ParentProgress parentProgress = ParentProgress(children, weights);

// 示例:更新并获取总进度
child1.finishProgressUpToIndexLevel(processIndexLevel: 0, processingLenghtPerS: 10, updateIntervalMs: 100);
child2.currentWorkDone(100);
print("Total aggregated progress: ${parentProgress.percentageNotifier.value}%");

完整示例

以下是一个完整的示例,展示了如何使用 ParentProgress 插件。

import 'package:flutter/material.dart';
import 'package:parent_progress/parent_progress.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        colorSchemeSeed: Colors.greenAccent,
        brightness: Brightness.dark,
        useMaterial3: true,
      ),
      home: const ParentProgressDemo(),
    );
  }
}

class ParentProgressDemo extends StatefulWidget {
  const ParentProgressDemo({super.key});

  [@override](/user/override)
  State<ParentProgressDemo> createState() => _ParentProgressDemoState();
}

class _ParentProgressDemoState extends State<ParentProgressDemo> {
  late FictionalProgress _fictionalProgress;
  late RationalProgress _rationalProgress;
  late ParentProgress _parentProgress;

  [@override](/user/override)
  void initState() {
    super.initState();
    _fictionalProgress =
        FictionalProgress([10, 20, 30, 40], uniqueName: "Fictional Progress");
    _rationalProgress = RationalProgress(
        totalWork: 100.0,
        smoothUpdateInterval: 50,
        uniqueName: "Rational Progress");

    // 父进度初始化,使用两个进度指示器的通知器
    _parentProgress = ParentProgress(
      [_fictionalProgress, _rationalProgress],
      [60, 40], // 假设权重相等
    );
  }

  [@override](/user/override)
  void dispose() {
    _fictionalProgress.dispose();
    _rationalProgress.dispose();
    _parentProgress.dispose();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: SingleChildScrollView(
          padding: const EdgeInsets.symmetric(horizontal: 8),
          child: Column(
            children: [
              Card(
                child: SizedBox(
                  width: double.infinity,
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: ValueListenableBuilder<int>(
                      valueListenable: _parentProgress.percentageNotifier,
                      builder: (_, totalPercentage, __) {
                        return Column(
                          children: [
                            Text('Parent Progress Value: $totalPercentage%'),
                            Padding(
                              padding: const EdgeInsets.symmetric(vertical: 8.0),
                              child: CircularProgressIndicator(
                                backgroundColor: Colors.greenAccent.withOpacity(0.1),
                                value: totalPercentage / 100.0,
                                strokeWidth: 8.0,
                              ),
                            ),
                            Text('${_parentProgress.getChildren[0].uniqueName} Factor: ${_parentProgress.getFlexFactors[0]}'),
                            Text('${_parentProgress.getChildren[1].uniqueName} Factor: ${_parentProgress.getFlexFactors[1]}'),
                          ],
                        );
                      },
                    ),
                  ),
                ),
              ),
              const SizedBox(
                height: 4,
              ),
              SizedBox(
                height: 400,
                child: Card(
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: FictionalProgressDemo(fictionalProgress: _fictionalProgress),
                  ),
                ),
              ),
              const SizedBox(
                height: 4,
              ),
              Card(
                child: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: RationalProgressDemo(rationalProgress: _rationalProgress),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class FictionalProgressDemo extends StatefulWidget {
  final FictionalProgress fictionalProgress; // 从父组件获取FictionalProgress实例

  const FictionalProgressDemo({
    super.key,
    required this.fictionalProgress, // 通过构造函数注入依赖
  });

  [@override](/user/override)
  State<FictionalProgressDemo> createState() => _FictionalProgressDemoState();
}

class _FictionalProgressDemoState extends State<FictionalProgressDemo> {
  late FictionalProgress fictionalProgress;

  double _processingLenghtPerS = 5.0; // 每秒处理的数量,可调
  int _updateIntervalMs = 50; // 更新间隔(毫秒),可调

  [@override](/user/override)
  void initState() {
    super.initState();
    fictionalProgress = widget.fictionalProgress;
  }

  [@override](/user/override)
  void dispose() {
    super.dispose();
  }

  void startProgressSimulation(int index) {
    fictionalProgress.finishProgressUpToIndexLevel(
      processIndexLevel: index,
      processingLenghtPerS: _processingLenghtPerS,
      updateIntervalMs: _updateIntervalMs,
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ValueListenableBuilder<int>(
          valueListenable: fictionalProgress.percentageNotifier,
          builder: (_, percentage, __) {
            return Column(
              children: [
                Text('Fictional Progress Value: $percentage%'),
                LinearProgressIndicator(
                  backgroundColor: Colors.white.withOpacity(0.14),
                  value: percentage / 100.0,
                  minHeight: 20,
                  borderRadius: BorderRadius.circular(8),
                ),
              ],
            );
          },
        ),
        ValueListenableBuilder<double>(
          valueListenable: fictionalProgress.processedSizeNotifier,
          builder: (_, processedSize, __) {
            return Text('${processedSize.toStringAsFixed(2)} / ${fictionalProgress.getTotalSize} units');
          },
        ),
        Slider(
          min: 1,
          max: 10,
          divisions: 9,
          label: 'Processing rate: $_processingLenghtPerS units/s',
          value: _processingLenghtPerS,
          onChanged: (double value) {
            setState(() {
              fictionalProgress.processingLenghtPerS = value;
              _processingLenghtPerS = value;
            });
          },
          inactiveColor: Colors.greenAccent.withOpacity(0.1),
        ),
        Slider(
          min: 20,
          max: 1000,
          divisions: 49,
          label: 'Update interval: $_updateIntervalMs ms',
          value: _updateIntervalMs.toDouble(),
          onChanged: (double value) {
            setState(() {
              fictionalProgress.setUpdateIntervalMs = value.toInt();
              _updateIntervalMs = value.toInt();
            });
          },
          inactiveColor: Colors.greenAccent.withOpacity(0.1),
        ),
        Expanded(
          child: ListView.builder(
            itemCount: fictionalProgress.getSizes.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text('Simulate Progress up to step ${index + 1}'),
                subtitle: Text('Step size: ${fictionalProgress.getSizes[index]} units'),
                onTap: () => fictionalProgress.finishProgressUpToIndexLevel(
                  processIndexLevel: index,
                  processingLenghtPerS: _processingLenghtPerS,
                  updateIntervalMs: _updateIntervalMs,
                ),
              );
            },
          ),
        ),
        ElevatedButton(
          onPressed: () {
            setState(() {
              fictionalProgress.resetProgress();
            });
          },
          child: const Text('Reset Fictional Progress'),
        ),
      ],
    );
  }
}

class RationalProgressDemo extends StatefulWidget {
  final RationalProgress rationalProgress; // 从父组件获取RationalProgress实例

  const RationalProgressDemo({
    super.key,
    required this.rationalProgress, // 通过构造函数注入依赖
  });

  [@override](/user/override)
  State<RationalProgressDemo> createState() => _RationalProgressDemoState();
}

class _RationalProgressDemoState extends State<RationalProgressDemo> {
  late RationalProgress rationalProgress;
  double _sliderValue = 0.0; // 独立的状态变量用于滑块

  [@override](/user/override)
  void initState() {
    super.initState();
    rationalProgress = widget.rationalProgress;
  }

  [@override](/user/override)
  void dispose() {
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ValueListenableBuilder<int>(
            valueListenable: rationalProgress.percentageNotifier,
            builder: (_, currentPercentage, __) {
              return Column(children: [
                Text('Rational Progress Value: $currentPercentage%'),
                LinearProgressIndicator(
                  backgroundColor: Colors.white.withOpacity(0.14),
                  value: currentPercentage / 100.0,
                  minHeight: 20,
                  borderRadius: BorderRadius.circular(8),
                ),
              ]);
            }),
        Text('${_sliderValue.toStringAsFixed(0)} MB / ${rationalProgress.getTotalWork.toStringAsFixed(0)} MB'), // 显示滑块的当前值
        Slider(
          min: 0,
          max: rationalProgress.getTotalWork,
          value: _sliderValue,
          onChanged: (value) {
            setState(() {
              _sliderValue = value; // 更新滑块值
            });
            rationalProgress.currentWorkDone(value);
          },
          inactiveColor: Colors.greenAccent.withOpacity(0.1),
        ),
        ElevatedButton(
          child: const Text("Reset Rational Progress"),
          onPressed: () {
            setState(() {
              _sliderValue = 0; // 重置滑块值
            });
            rationalProgress.resetProgress();
          },
        ),
      ],
    );
  }
}

更多关于Flutter父级进度条管理插件parent_progress的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter父级进度条管理插件parent_progress的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用parent_progress插件的一个示例。这个插件允许你在Flutter应用中管理父级进度条。假设你已经将parent_progress插件添加到了你的pubspec.yaml文件中。

首先,确保你的pubspec.yaml文件中包含以下依赖项:

dependencies:
  flutter:
    sdk: flutter
  parent_progress: ^最新版本号  # 请替换为实际的最新版本号

然后,运行flutter pub get来安装依赖项。

接下来,让我们编写一个示例应用,展示如何使用parent_progress插件。

主应用文件 (main.dart)

import 'package:flutter/material.dart';
import 'package:parent_progress/parent_progress.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Parent Progress Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ParentProgressDemo(),
    );
  }
}

class ParentProgressDemo extends StatefulWidget {
  @override
  _ParentProgressDemoState createState() => _ParentProgressDemoState();
}

class _ParentProgressDemoState extends State<ParentProgressDemo> with ParentProgressListener {
  late ParentProgressController _parentProgressController;

  @override
  void initState() {
    super.initState();
    _parentProgressController = ParentProgressController();
    _parentProgressController.addListener(this);
  }

  @override
  void dispose() {
    _parentProgressController.removeListener(this);
    _parentProgressController.dispose();
    super.dispose();
  }

  @override
  void onParentProgressChanged(double progress) {
    // 更新UI或执行其他操作
    print("Parent progress: $progress");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Parent Progress Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ParentProgressIndicator(
              controller: _parentProgressController,
              child: Container(
                height: 200,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    ElevatedButton(
                      onPressed: () {
                        // 模拟子任务进度
                        simulateChildProgress();
                      },
                      child: Text('Start Child Progress'),
                    ),
                  ],
                ),
              ),
            ),
            SizedBox(height: 20),
            Text(
              'Current Parent Progress: ${_parentProgressController.progress.toStringAsFixed(2)}',
              style: TextStyle(fontSize: 20),
            ),
          ],
        ),
      ),
    );
  }

  void simulateChildProgress() {
    // 模拟子任务进度更新
    for (int i = 0; i <= 100; i += 10) {
      Future.delayed(Duration(seconds: 1), () {
        _parentProgressController.updateProgress(i.toDouble() / 100);
      });
    }
  }
}

解释

  1. ParentProgressController: 创建了一个ParentProgressController实例,用于管理进度。
  2. ParentProgressListener: 通过实现ParentProgressListener接口,可以监听进度变化。
  3. ParentProgressIndicator: 使用ParentProgressIndicator小部件来显示父级进度条。
  4. simulateChildProgress: 模拟子任务进度更新,每秒钟增加10%的进度。

在这个示例中,当你点击“Start Child Progress”按钮时,进度条将模拟更新,并且每次更新都会触发onParentProgressChanged方法,打印当前的父级进度。

请根据你的实际需求调整此示例。如果你有更复杂的需求,例如多个子任务或动态添加子任务,你可能需要更复杂的逻辑来管理进度。

回到顶部