Flutter – 步进器小部件
在本文中,我们将了解Flutter中的Stepper 小部件。步进器小部件通过一系列步骤显示进度。 Stepper 一般用于在线填写表格。
例如,请记住填写申请任何大学或护照或驾驶执照的在线表格。我们一步一步填写表格
- 在 第 1 步我们已经填写了我们的个人信息
- 在第 2 步中,我们输入了我们的居住地址
- 在步骤 3 我们已经提供了我们的教育细节
- 在第 4 步中,我们进行了付款
- 在第 5 步中,我们注册并打印收据
这实际上称为Stepper 。分步执行任务。
现在让我们看看我们的步进器小部件的实际实现:
第 1 步:在您的编辑器中打开一个新的flutter项目。
第 2 步:在脚手架中,我们初始化了Stepper()并在 stepper 内部创建了一个名为stepList()的方法。创建此方法是因为我们已经创建了表单中所需的步骤列表。
Dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
// Here we have created list of steps that
// are required to complete the form
List stepList() => [
const Step(title: Text('Account'), content: Center(child: Text('Account'),)),
const Step(title: Text('Address'), content: Center(child: Text('Address'),)),
const Step(title: Text('Confirm'), content: Center(child: Text('Confirm'),))
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
backgroundColor: Colors.green,
title: const Text('GeeksforGeeks',style: TextStyle(color: Colors.white), ),
),
// Here we have initialized the stepper widget
body: Stepper(
steps: stepList(),
)
);
}
}
Dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
// we have initialized active step to 0 so that
// our stepper widget will start from first step
int _activeCurrentStep = 0;
TextEditingController name = TextEditingController();
TextEditingController email = TextEditingController();
TextEditingController pass = TextEditingController();
TextEditingController address = TextEditingController();
TextEditingController pincode = TextEditingController();
// Here we have created list of steps
// that are required to complete the form
List stepList() => [
// This is step1 which is called Account.
// Here we will fill our personal details
Step(
state: _activeCurrentStep <= 0 ? StepState.editing : StepState.complete,
isActive: _activeCurrentStep >= 0,
title: const Text('Account'),
content: Container(
child: Column(
children: [
TextField(
controller: name,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Full Name',
),
),
const SizedBox(
height: 8,
),
TextField(
controller: email,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
),
),
const SizedBox(
height: 8,
),
TextField(
controller: pass,
obscureText: true,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
),
),
],
),
),
),
// This is Step2 here we will enter our address
Step(
state:
_activeCurrentStep <= 1 ? StepState.editing : StepState.complete,
isActive: _activeCurrentStep >= 1,
title: const Text('Address'),
content: Container(
child: Column(
children: [
const SizedBox(
height: 8,
),
TextField(
controller: address,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Full House Address',
),
),
const SizedBox(
height: 8,
),
TextField(
controller: pincode,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Pin Code',
),
),
],
),
)),
// This is Step3 here we will display all the details
// that are entered by the user
Step(
state: StepState.complete,
isActive: _activeCurrentStep >= 2,
title: const Text('Confirm'),
content: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('Name: ${name.text}'),
Text('Email: ${email.text}'),
Text('Password: ${pass.text}'),
Text('Address : ${address.text}'),
Text('PinCode : ${pincode.text}'),
],
)))
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
backgroundColor: Colors.green,
title: const Text('GeeksforGeeks',style: TextStyle(color: Colors.white), ),
),
// Here we have initialized the stepper widget
body: Stepper(
type: StepperType.horizontal,
currentStep: _activeCurrentStep,
steps: stepList(),
// onStepContinue takes us to the next step
onStepContinue: () {
if (_activeCurrentStep < (stepList().length - 1)) {
setState(() {
_activeCurrentStep += 1;
});
}
},
// onStepCancel takes us to the previous step
onStepCancel: () {
if (_activeCurrentStep == 0) {
return;
}
setState(() {
_activeCurrentStep -= 1;
});
},
// onStepTap allows to directly click on the particular step we want
onStepTapped: (int index) {
setState(() {
_activeCurrentStep = index;
});
},
),
);
}
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
int _activeCurrentStep = 0;
TextEditingController name = TextEditingController();
TextEditingController email = TextEditingController();
TextEditingController pass = TextEditingController();
TextEditingController address = TextEditingController();
TextEditingController pincode = TextEditingController();
List stepList() => [
Step(
state: _activeCurrentStep <= 0 ? StepState.editing : StepState.complete,
isActive: _activeCurrentStep >= 0,
title: const Text('Account'),
content: Container(
child: Column(
children: [
TextField(
controller: name,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Full Name',
),
),
const SizedBox(
height: 8,
),
TextField(
controller: email,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
),
),
const SizedBox(
height: 8,
),
TextField(
controller: pass,
obscureText: true,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
),
),
],
),
),
),
Step(
state:
_activeCurrentStep <= 1 ? StepState.editing : StepState.complete,
isActive: _activeCurrentStep >= 1,
title: const Text('Address'),
content: Container(
child: Column(
children: [
const SizedBox(
height: 8,
),
TextField(
controller: address,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Full House Address',
),
),
const SizedBox(
height: 8,
),
TextField(
controller: pincode,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Pin Code',
),
),
],
),
)),
Step(
state: StepState.complete,
isActive: _activeCurrentStep >= 2,
title: const Text('Confirm'),
content: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('Name: ${name.text}'),
Text('Email: ${email.text}'),
Text('Password: ${pass.text}'),
Text('Address : ${address.text}'),
Text('PinCode : ${pincode.text}'),
],
)))
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Stepper'),
),
body: Stepper(
type: StepperType.horizontal,
currentStep: _activeCurrentStep,
steps: stepList(),
onStepContinue: () {
if (_activeCurrentStep < (stepList().length - 1)) {
setState(() {
_activeCurrentStep += 1;
});
}
},
onStepCancel: () {
if (_activeCurrentStep == 0) {
return;
}
setState(() {
_activeCurrentStep -= 1;
});
},
onStepTapped: (int index) {
setState(() {
_activeCurrentStep = index;
});
},
),
);
}
}
输出:
注意:现在,这是基本的步进器小部件。如果我们愿意,我们也可以更改水平形式的步进器。只需在下图中输入命令
输出:
第 3 步:现在让我们向这个 Stepper Widget 添加属性,例如 –
- currentStep:我们创建了一个整数。它的初始值为 0。它实际上显示了该特定索引所在的步骤的内容。
- onStepContinue:点击继续按钮时调用的回调。当我们点击继续按钮时,它会将我们带到下一步。如果为空,“继续”按钮将被禁用
- onStepCancel:点击取消按钮时调用的回调。当我们点击取消按钮时,我们将推回到上一步。如果为空,“取消”按钮将被禁用。
- onStepTapped:点击步骤时调用的回调。我们可以通过单击该特定步骤直接进入任何步骤。例如——如果你想直接进入第 2 步,那么只需点击它,你就会在那里。
第 4 步:在这一步中,我们通过添加文本字段创建了一个表单,以便用户可以输入数据。所以它基本上看起来更像是一个类似形式的结构。
- 在第一步Account中,我们添加了 texfields – Full Name, Email, Password
- 在第二步Address中,我们创建了文本字段 - Full house Address, Pin Code 。
- 在第三步中,确认我们正在显示用户输入的数据。
完整源代码:
Dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
// we have initialized active step to 0 so that
// our stepper widget will start from first step
int _activeCurrentStep = 0;
TextEditingController name = TextEditingController();
TextEditingController email = TextEditingController();
TextEditingController pass = TextEditingController();
TextEditingController address = TextEditingController();
TextEditingController pincode = TextEditingController();
// Here we have created list of steps
// that are required to complete the form
List stepList() => [
// This is step1 which is called Account.
// Here we will fill our personal details
Step(
state: _activeCurrentStep <= 0 ? StepState.editing : StepState.complete,
isActive: _activeCurrentStep >= 0,
title: const Text('Account'),
content: Container(
child: Column(
children: [
TextField(
controller: name,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Full Name',
),
),
const SizedBox(
height: 8,
),
TextField(
controller: email,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
),
),
const SizedBox(
height: 8,
),
TextField(
controller: pass,
obscureText: true,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
),
),
],
),
),
),
// This is Step2 here we will enter our address
Step(
state:
_activeCurrentStep <= 1 ? StepState.editing : StepState.complete,
isActive: _activeCurrentStep >= 1,
title: const Text('Address'),
content: Container(
child: Column(
children: [
const SizedBox(
height: 8,
),
TextField(
controller: address,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Full House Address',
),
),
const SizedBox(
height: 8,
),
TextField(
controller: pincode,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Pin Code',
),
),
],
),
)),
// This is Step3 here we will display all the details
// that are entered by the user
Step(
state: StepState.complete,
isActive: _activeCurrentStep >= 2,
title: const Text('Confirm'),
content: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('Name: ${name.text}'),
Text('Email: ${email.text}'),
Text('Password: ${pass.text}'),
Text('Address : ${address.text}'),
Text('PinCode : ${pincode.text}'),
],
)))
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
backgroundColor: Colors.green,
title: const Text('GeeksforGeeks',style: TextStyle(color: Colors.white), ),
),
// Here we have initialized the stepper widget
body: Stepper(
type: StepperType.horizontal,
currentStep: _activeCurrentStep,
steps: stepList(),
// onStepContinue takes us to the next step
onStepContinue: () {
if (_activeCurrentStep < (stepList().length - 1)) {
setState(() {
_activeCurrentStep += 1;
});
}
},
// onStepCancel takes us to the previous step
onStepCancel: () {
if (_activeCurrentStep == 0) {
return;
}
setState(() {
_activeCurrentStep -= 1;
});
},
// onStepTap allows to directly click on the particular step we want
onStepTapped: (int index) {
setState(() {
_activeCurrentStep = index;
});
},
),
);
}
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
int _activeCurrentStep = 0;
TextEditingController name = TextEditingController();
TextEditingController email = TextEditingController();
TextEditingController pass = TextEditingController();
TextEditingController address = TextEditingController();
TextEditingController pincode = TextEditingController();
List stepList() => [
Step(
state: _activeCurrentStep <= 0 ? StepState.editing : StepState.complete,
isActive: _activeCurrentStep >= 0,
title: const Text('Account'),
content: Container(
child: Column(
children: [
TextField(
controller: name,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Full Name',
),
),
const SizedBox(
height: 8,
),
TextField(
controller: email,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
),
),
const SizedBox(
height: 8,
),
TextField(
controller: pass,
obscureText: true,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
),
),
],
),
),
),
Step(
state:
_activeCurrentStep <= 1 ? StepState.editing : StepState.complete,
isActive: _activeCurrentStep >= 1,
title: const Text('Address'),
content: Container(
child: Column(
children: [
const SizedBox(
height: 8,
),
TextField(
controller: address,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Full House Address',
),
),
const SizedBox(
height: 8,
),
TextField(
controller: pincode,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Pin Code',
),
),
],
),
)),
Step(
state: StepState.complete,
isActive: _activeCurrentStep >= 2,
title: const Text('Confirm'),
content: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('Name: ${name.text}'),
Text('Email: ${email.text}'),
Text('Password: ${pass.text}'),
Text('Address : ${address.text}'),
Text('PinCode : ${pincode.text}'),
],
)))
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Stepper'),
),
body: Stepper(
type: StepperType.horizontal,
currentStep: _activeCurrentStep,
steps: stepList(),
onStepContinue: () {
if (_activeCurrentStep < (stepList().length - 1)) {
setState(() {
_activeCurrentStep += 1;
});
}
},
onStepCancel: () {
if (_activeCurrentStep == 0) {
return;
}
setState(() {
_activeCurrentStep -= 1;
});
},
onStepTapped: (int index) {
setState(() {
_activeCurrentStep = index;
});
},
),
);
}
}
输出:
说明– 在此视频中,我们可以看到:
- 当我们点击继续按钮时,我们将进入下一步,这意味着我们的onStepContinue属性正在工作。
- 当我们点击取消按钮时,我们将回到上一步,这意味着我们的onStepCancel属性正在工作。
- 当我们点击特定步骤时,我们会直接进入该特定步骤,这意味着我们的onStepTapped属性正在工作。