1. 基本介紹
Stepper 是 flutter 提供的步驟選擇器。
Stepper.png
2. 示例代碼
代碼下載地址。如果對(duì)你有幫助的話記得給個(gè)關(guān)注,代碼會(huì)根據(jù)我的 Flutter 專題不斷更新堕担。
3. 屬性介紹
Stepper 屬性 | 介紹 |
---|---|
steps | @required |
physics | 滑動(dòng)的物理效果 |
type | Stepper 類型,分為橫向與縱向兩種,默認(rèn)為 StepperType.vertical |
currentStep | 當(dāng)前 step讽营,默認(rèn)為 0 |
onStepTapped | step 點(diǎn)擊回調(diào)函數(shù) |
onStepContinue | Next 按鈕點(diǎn)擊回調(diào)函數(shù) |
onStepCancel | Cancel 按鈕點(diǎn)擊回調(diào)函數(shù) |
controlsBuilder | 內(nèi)容下方按鈕構(gòu)建函數(shù) |
Step 屬性 | 介紹 |
---|---|
title | @required 標(biāo)題控件 |
subtitle | 副標(biāo)題控件 |
content | @required 內(nèi)容控件 |
state | 當(dāng)前 step 的狀態(tài),StepState 會(huì)改變每一個(gè) step 的圖標(biāo)泡徙,默認(rèn)為 StepState.indexed |
isActive | 是否激活狀態(tài)橱鹏,默認(rèn)為 false,isActive == true 時(shí)會(huì)變成藍(lán)色 |
4. Stepper 詳解
Stepper 的屬性其實(shí)比較簡單堪藐,更多的其實(shí)是 Stepper 之外的邏輯莉兰,在文章末尾會(huì)對(duì)整體思路進(jìn)行歸納。
import 'package:flutter/material.dart';
class FMStepperVC extends StatefulWidget{
@override
FMStepperState createState() => FMStepperState();
}
class FMStepperState extends State <FMStepperVC>{
int _currentStep = 0;
List <FMStepperModel> _datas = [];
@override
void initState(){
super.initState();
initData();
}
void initData(){
_datas.clear();
_datas.add(FMStepperModel("第一步", "我們先進(jìn)行第一步", 0));
_datas.add(FMStepperModel("第二步", "我們先進(jìn)行第二步", 1));
_datas.add(FMStepperModel("第三步", "我們先進(jìn)行第三步", 2));
_datas.add(FMStepperModel("第三步", "我們先進(jìn)行第四步", 3));
_datas.add(FMStepperModel("第三步", "我們先進(jìn)行第五步", 4));
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(title: Text("Stepper"),),
body: _listView(),
);
}
ListView _listView(){
return ListView(
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
width: 500,
height: 200,
child: _stepper(StepperType.horizontal),
),
),
Padding(
padding: EdgeInsets.all(15),
child: Container(
color: Colors.yellow,
height: 30,
alignment: Alignment.center,
child: Text("下方為縱向 Stepper"),
),
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
width: 400,
height: 500,
child: _stepper(StepperType.vertical),
),
),
],
);
}
Stepper _stepper(type){
return Stepper(
currentStep: _currentStep, // 當(dāng)前 step
physics: ClampingScrollPhysics(), // 滑動(dòng)的物理效果
type: type, // Stepper 類型礁竞,分為橫向與縱向兩種糖荒, StepperType
// 內(nèi)容下方按鈕構(gòu)建函數(shù)
controlsBuilder: (BuildContext context, {VoidCallback onStepContinue, VoidCallback onStepCancel}) {
return Row(
children: <Widget>[
FlatButton(
onPressed: onStepContinue,
child: const Text('NEXT'),
),
FlatButton(
onPressed: onStepCancel,
child: const Text('CANCEL'),
),
FlatButton(
onPressed: (){
print("自定義按鈕點(diǎn)擊事件");
},
child: const Text('自定義按鈕'),
)
],
);
},
// step 點(diǎn)擊回調(diào)函數(shù)
onStepTapped: (index){
print(index);
_currentStep = index;
setState(() {
});
},
// Cancel 按鈕點(diǎn)擊回調(diào)函數(shù)
onStepCancel: (){
if(_currentStep > 0){
_currentStep--;
}
setState(() {
});
},
// Next 按鈕點(diǎn)擊回調(diào)函數(shù)
onStepContinue: (){
if(_currentStep < _datas.length - 1){
_currentStep++;
}
setState(() {
});
},
// <Step> 子控件數(shù)組
steps: _steps(),
);
}
// 創(chuàng)建 <Step> steps 數(shù)組
List <Step> _steps(){
List <Step> steps = [];
_datas.forEach((model) {
// 我們根據(jù)當(dāng)前 step 進(jìn)行區(qū)分,當(dāng)前 step 之前的認(rèn)為 StepState.complete模捂,當(dāng)前認(rèn)為 StepState.editing捶朵,之后認(rèn)為 StepState.indexed
if(_currentStep < model.index) {
model.state = StepState.indexed;
} else if(_currentStep == model.index) {
model.state = StepState.editing;
} else if(_currentStep > model.index){
model.state = StepState.complete;
}
steps.add(
Step(
// 標(biāo)題控件
title: Row(
children: [
Icon(Icons.title),
Text("title"),
],
),
subtitle: Text("subTitle"), // 副標(biāo)題控件
content: Text("${model.content}"), // 內(nèi)容控件
isActive: (_currentStep == _datas.indexOf(model)), // 是否激活狀態(tài),true 時(shí)會(huì)變成藍(lán)色
state: model.state, // 當(dāng)前 step 的狀態(tài)枫绅,StepState 會(huì)改變每一個(gè) step 的圖標(biāo)
),
);
});
return steps;
}
}
class FMStepperModel {
String title;
String content;
int index;
StepState state = StepState.indexed;
FMStepperModel(this.title, this.content, this.index);
}
Stepper.gif
5. 技術(shù)小結(jié)
- 第一步泉孩,我們既然要做一個(gè) Stepper,我們要準(zhǔn)備一套數(shù)據(jù)模型并淋,并且模型包含了狀態(tài)寓搬,標(biāo)題,內(nèi)容县耽,下標(biāo)句喷,等各個(gè)元素镣典,然后將這些數(shù)據(jù)構(gòu)造出來當(dāng)做數(shù)據(jù)源。
- 第二步唾琼,我們創(chuàng)建 Stepper兄春,并對(duì)一些屬性進(jìn)行設(shè)置。
- 第三步锡溯,我們創(chuàng)建 steps赶舆,這里很重要,要根據(jù)我們第一步中的數(shù)據(jù)源祭饭,將每一個(gè) model 構(gòu)造成對(duì)應(yīng)的 Step 控件芜茵。
- 第四步,我們?cè)趧?chuàng)建 steps 時(shí)倡蝙,對(duì) model 的狀態(tài)進(jìn)行管理九串,設(shè)置編輯中,已完成寺鸥,未完成等不同狀態(tài)猪钮。
- 第五步,我們對(duì) Stepper 的交互事件進(jìn)行處理胆建,點(diǎn)擊時(shí)將 currentStep 設(shè)置到對(duì)應(yīng) index烤低,cancel 時(shí)我們執(zhí)行 currentStep -1 操作,Next 時(shí)我們執(zhí)行 currentStep +1 操作眼坏,此處注意防止越界拂玻。