Flutter步进器控件插件fine_stepper的使用

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

Flutter步进器控件插件fine_stepper的使用

fine_stepper 是一个用于创建水平步进器的Flutter插件,它提供了简单易用的API来控制步进器的状态,并且可以在 widget 树的任何位置进行控制。以下是关于 fine_stepper 插件的详细使用说明和完整示例代码。

1. Icon Stepper

通过 FineStepper.icon 构造函数可以创建带有图标的步进器。每个步骤可以通过 StepItem.icon 来定义,并且可以自定义每个步骤的内容。

Icon Stepper 示例

FineStepper.icon(
  steps: [
    StepItem.icon(
      builder: (context) => StepBuilder(
        child: Text('Step ${FineStepper.of(context).stepIndex}'),
      ),
    ),
    StepItem.icon(
      builder: (context) => StepBuilder(
        child: Text('Step ${FineStepper.of(context).stepIndex}'),
      ),
    ),
    StepItem.icon(
      builder: (context) => StepBuilder(
        child: Text('Step ${FineStepper.of(context).stepIndex}'),
      ),
    )
  ],
),

2. Linear Stepper

通过 FineStepper.linear 构造函数可以创建线性步进器。每个步骤可以通过 StepItem.linear 来定义,并且可以为每个步骤添加标题和描述。

Linear Stepper 示例

FineStepper.linear(
  steps: [
    StepItem.linear(
      title: 'Step 1',
      description: '这是描述',
      builder: (context) => StepBuilder(
        child: Text('Step ${FineStepper.of(context).stepIndex}'),
      ),
    ),
    StepItem.linear(
      title: 'Step 2',
      builder: (context) => StepBuilder(
        child: Text('Step ${FineStepper.of(context).stepIndex}'),
      ),
    ),
    StepItem.linear(
      title: 'Step 3',
      builder: (context) => StepBuilder(
        child: Text('Step ${FineStepper.of(context).stepIndex}'),
      ),
    )
  ],
),

3. StepBuilder

StepBuilder 提供了两种布局选项来控制步进器的导航按钮:

  • StepLayout.stack(默认):将子组件占据可用高度,并在底部居中添加导航按钮。
  • StepLayout.column:将子组件占据最小高度,并在下方添加导航按钮。
StepLayout.stack 示例

StepLayout.stack 示例

StepBuilder(
  child: SizedBox(
    width: MediaQuery.of(context).size.width,
    child: Padding(
      padding: const EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            'Step ${FineStepper.of(context).stepIndex + 1}',
            style: Theme.of(context).textTheme.bodyLarge,
          ),
          Text(
            'StepLayout: Stack',
            style: Theme.of(context).textTheme.bodyLarge,
          ),
        ],
      ),
    ),
  ),
);
StepLayout.column 示例

StepLayout.column 示例

StepBuilder(
  layout: StepLayout.column,
  child: SizedBox(
    width: MediaQuery.of(context).size.width,
    child: Padding(
      padding: const EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            'Step ${FineStepper.of(context).stepIndex + 1}',
            style: Theme.of(context).textTheme.bodyLarge,
          ),
          Text(
            'StepLayout: Column',
            style: Theme.of(context).textTheme.bodyLarge,
          ),
        ],
      ),
    ),
  ),
);

4. FormStepBuilder

FormStepBuilderStepBuilder 类似,但在前进到下一步之前会验证表单字段。

FormStepBuilder(
  child: TextFormField(
    decoration: const InputDecoration(hintText: '示例'),
    // 验证器在调用 FineStepper.of(context).stepForward 时执行
    validator: (value) => (value?.isEmpty ?? true) ? '必填项' : null,
  ),
),

5. StepperController

StepperController 提供了访问和控制步进器状态的API。你可以通过 FineStepper.of(context) 获取控制器实例,并使用以下方法:

  • int get stepIndex:获取当前步骤索引。
  • set stepIndex(int index):设置当前步骤索引。
  • bool get isFirstStep:检查是否是第一步。
  • bool get isLastStep:检查是否是最后一步。
  • bool get finishing:检查是否正在完成。
  • void stepBack():返回上一步。
  • Future<void> stepForward():前进到下一步。

6. IndicatorOptions

你可以通过传递 IndicatorOptions 对象来自定义步进器指示器的颜色和其他属性。

FineStepper.icon(
  indicatorOptions: const IndicatorOptions(
    activeStepColor: Colors.blue, // 激活步骤的颜色
    completedStepColor: Colors.green, // 完成步骤的颜色
    stepColor: Colors.grey, // 默认步骤颜色
    padding: EdgeInsets.all(8), // 指示器内边距
    scrollable: true, // 是否可滚动(仅对 Icon Stepper 有效)
  ),
  // 其他配置...
)

7. 完整示例代码

以下是一个完整的示例代码,展示了如何使用 fine_stepper 插件创建图标步进器和线性步进器,并在底部导航栏中切换它们。

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

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

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

  [@override](/user/override)
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  int index = 0;

  Widget iconExample() {
    return FineStepper.icon(
      onFinish: () => Future.delayed(const Duration(seconds: 2)),
      indicatorOptions: const IndicatorOptions(scrollable: true),
      steps: [
        StepItem.icon(builder: buildColumnStep),
        StepItem.icon(builder: buildStackStep),
        StepItem.icon(builder: buildCustomStep),
        StepItem.icon(builder: buildFormStep),
        StepItem.icon(builder: buildFormStep),
        StepItem.icon(builder: buildFormStep),
      ],
    );
  }

  Widget linearExample() {
    return FineStepper.linear(
      onFinish: () => Future.delayed(const Duration(seconds: 2)),
      steps: [
        StepItem.linear(
          title: '步骤 1',
          description: '这是描述',
          builder: buildColumnStep,
        ),
        StepItem.linear(
          title: '步骤 2',
          builder: buildStackStep,
        ),
        StepItem.linear(
          title: '步骤 3',
          builder: buildStackStep,
        ),
        StepItem.linear(
          title: '步骤 4',
          builder: buildFormStep,
        ),
        StepItem.linear(
          title: '步骤 5',
          builder: buildFormStep,
        ),
        StepItem.linear(
          title: '步骤 5',
          builder: buildFormStep,
        ),
      ],
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(colorSchemeSeed: const Color.fromARGB(255, 49, 255, 252)),
      home: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: const Text('Fine Stepper 示例'),
        ),
        body: Builder(
          builder: (context) {
            if (index == 0) {
              return iconExample();
            }
            return linearExample();
          },
        ),
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: index,
          onTap: (value) => setState(() {
            index = value;
          }),
          items: const [
            BottomNavigationBarItem(
              label: '图标',
              icon: Icon(Icons.image),
            ),
            BottomNavigationBarItem(
              label: '线性',
              icon: Icon(Icons.linear_scale),
            ),
          ],
        ),
      ),
    );
  }

  Widget buildStackStep(BuildContext context) {
    return StepBuilder(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Padding(
            padding: const EdgeInsets.all(16),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '步骤 ${FineStepper.of(context).stepIndex + 1}',
                  style: Theme.of(context).textTheme.bodyLarge,
                ),
                Text(
                  'StepLayout: Stack',
                  style: Theme.of(context).textTheme.bodyLarge,
                ),
              ],
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: 20,
              itemBuilder: (context, index) {
                return CheckboxListTile(
                  onChanged: (_) {},
                  value: false,
                  title: Text('项目 $index'),
                );
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget buildColumnStep(BuildContext context) {
    return StepBuilder(
      layout: StepLayout.column,
      child: SizedBox(
        width: MediaQuery.of(context).size.width,
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                '步骤 ${FineStepper.of(context).stepIndex + 1}',
                style: Theme.of(context).textTheme.bodyLarge,
              ),
              Text(
                'StepLayout: Column',
                style: Theme.of(context).textTheme.bodyLarge,
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget buildFormStep(BuildContext context) {
    return FormStepBuilder(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '步骤 ${FineStepper.of(context).stepIndex + 1}',
                  style: Theme.of(context).textTheme.bodyLarge,
                ),
                Text(
                  'StepLayout: Stack',
                  style: Theme.of(context).textTheme.bodyLarge,
                ),
              ],
            ),
            const SizedBox(height: 20),
            TextFormField(
              decoration: const InputDecoration(hintText: '示例'),
              validator: (value) => (value?.isEmpty ?? true) ? '必填项' : null,
            ),
          ],
        ),
      ),
    );
  }

  Widget buildCustomStep(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                '步骤 ${FineStepper.of(context).stepIndex + 1}',
                style: Theme.of(context).textTheme.bodyLarge,
              ),
              Text(
                '自定义',
                style: Theme.of(context).textTheme.bodyLarge,
              ),
            ],
          ),
          const Spacer(),
          Row(
            children: [
              FloatingActionButton(
                onPressed: () {
                  FineStepper.of(context).stepBack();
                },
                child: const Icon(Icons.arrow_back_ios),
              ),
              const Spacer(),
              FloatingActionButton(
                onPressed: () {
                  FineStepper.of(context).stepForward();
                },
                child: FineStepper.of(context).finishing
                    ? const CircularProgressIndicator.adaptive(backgroundColor: Colors.white)
                    : const Icon(Icons.arrow_forward_ios),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

更多关于Flutter步进器控件插件fine_stepper的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter步进器控件插件fine_stepper的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter应用中使用fine_stepper插件的示例代码。fine_stepper是一个用于创建步进器(Stepper)控件的Flutter插件,允许用户通过一系列步骤完成任务。

首先,确保你已经在pubspec.yaml文件中添加了fine_stepper依赖项:

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

然后运行flutter pub get来获取依赖项。

接下来是一个使用fine_stepper的简单示例:

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

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

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

class FineStepperDemo extends StatefulWidget {
  @override
  _FineStepperDemoState createState() => _FineStepperDemoState();
}

class _FineStepperDemoState extends State<FineStepperDemo> {
  int currentStep = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Fine Stepper Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: FineStepper(
          currentStep: currentStep,
          onStepContinue: (step) {
            setState(() {
              currentStep = step;
            });
          },
          onStepCancel: () {
            setState(() {
              if (currentStep > 0) {
                currentStep--;
              }
            });
          },
          onStepFinish: () {
            // 执行完成时的操作
            print('All steps completed!');
          },
          steps: [
            FineStep(
              title: Text('Step 1: Enter Name'),
              content: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  TextField(
                    decoration: InputDecoration(labelText: 'Name'),
                  ),
                ],
              ),
              actions: [
                ElevatedButton(
                  onPressed: () {
                    // 自定义继续按钮的行为
                    FineStepper.of(context)?.continueStep();
                  },
                  child: Text('Continue'),
                ),
              ],
            ),
            FineStep(
              title: Text('Step 2: Enter Age'),
              content: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  TextField(
                    decoration: InputDecoration(labelText: 'Age'),
                    keyboardType: TextInputType.number,
                  ),
                ],
              ),
              actions: [
                ElevatedButton(
                  onPressed: () {
                    FineStepper.of(context)?.continueStep();
                  },
                  child: Text('Continue'),
                ),
              ],
            ),
            FineStep(
              title: Text('Step 3: Summary'),
              content: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text('Name: '), // 这里可以动态显示用户输入的名字
                  Text('Age: '),  // 这里可以动态显示用户输入的年龄
                ],
              ),
              actions: [
                ElevatedButton(
                  onPressed: () {
                    FineStepper.of(context)?.finishStep();
                  },
                  child: Text('Finish'),
                ),
                TextButton(
                  onPressed: () {
                    FineStepper.of(context)?.cancelStep();
                  },
                  child: Text('Cancel'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个包含三个步骤的步进器:

  1. Step 1:用户输入名字。
  2. Step 2:用户输入年龄。
  3. Step 3:显示用户输入的总结信息,并提供完成和取消按钮。

每个步骤包含标题、内容和操作按钮。你可以根据需要自定义每个步骤的内容和行为。注意,FineStepper的上下文使用FineStepper.of(context)来获取,以便在按钮点击时调用相应的方法。

请确保你按照插件的最新文档进行使用,因为API可能会有所变化。

回到顶部