Flutter - 實作簡潔美觀的APP引導頁
前言
APP引導頁是一種互動式體驗,通常用於使用者首次安裝、啟動APP時顯示,透過展示APP功能、特色的價值,可以有效幫助新用戶快速掌握APP,並引導新用戶註冊登入。本文將實作三個分頁的引導頁,中間為擺放產品、功能的圖示區,並佐以標題、副標題說明; 左下角為分頁索引指示器,當前分頁索引為白色圓點,其餘的分頁為深色圓點; 右上角為略過按鈕,使用者可以略過引導流程,直接進到主流程(如註冊、登入); 右下角為開始使用按鈕,在使用者已完成引導流程後顯示。
完成圖
資料準備
標題字串
// TPIString.dart
const String tpiGetStarted = '開始使用';
const String tpiSkip = '略過';
const String tpiSlideOneTitle = 'DigiFusion 企業服務中台';
const String tpiSlideOneSubtitle =
'DigiFusion 透過微服務與 PaaS 架構,快速替企業打造服務中台,讓企業能快速開發應用服務並獲得良好的彈性與擴充性。';
const String tpiSlideTwoTitle = 'SysTalk.ai 交談式A產品';
const String tpiSlideTwoSubtitle =
'SysTalk.ai 以 AI 技術驅動人機協作,讓企業人力專注於更有價值的工作,快速改善企業流程並邁向智慧企業。';
const String tpiSlideThreeTitle = 'ESG Swift 永續產品與服務';
const String tpiSlideThreeSubtitle =
"一站式 ESG 資訊整合服務,結合專業顧問、碳盤查平台和 AI 節能系統,協助取得查證聲明與對外資訊公開揭露";
圖檔路徑
// TPIImage.dart
const String tpiSlideOneIc = 'images/tpi/flutter_digifusion.png';
const String tpiSlideTwoIc = 'images/tpi/flutter_systalk.png';
const String tpiSlideThreeIc = 'images/tpi/flutter_tpi.png';
顏色
// TPIColors.dart
Color tpiPrimaryColor = Colors.purple.shade500;
資料模型
// TPIWalkThroughData.dart
class TPIWalkThroughData {
// 圖檔路徑
String imagePath;
// 標題
String title;
// 副標題
String subtitle;
TPIWalkThroughData(
{this.imagePath = "", this.title = "", this.subtitle = ""});
}
導覽頁要呈現的分頁資料
// TPIDataProvider.dart
List<TPIWalkThroughData> tpiWalkThroughDataList() {
List<TPIWalkThroughData> list = [];
list.add(TPIWalkThroughData(
imagePath: tpiSlideOneIc,
title: tpiSlideOneTitle,
subtitle: tpiSlideOneSubtitle));
list.add(TPIWalkThroughData(
imagePath: tpiSlideTwoIc,
title: tpiSlideTwoTitle,
subtitle: tpiSlideTwoSubtitle));
list.add(TPIWalkThroughData(
imagePath: tpiSlideThreeIc,
title: tpiSlideThreeTitle,
subtitle: tpiSlideThreeSubtitle));
return list;
}
UI畫面
// TPIWalkThroughScreen.dart
class TPIWalkThroughScreen extends StatefulWidget {
@override
TPIWalkThroughScreenState createState() => TPIWalkThroughScreenState();
}
class TPIWalkThroughScreenState extends State<TPIWalkThroughScreen> {
// 操作、監聽PageView
PageController controller = PageController();
// 引導頁分頁資料
List<TPIWalkThroughData> list = tpiWalkThroughDataList();
// 當前分頁索引
int currentPageIndex = 0;
@override
void initState() {
super.initState();
init();
}
Future<void> init() async {
// TODO
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container();
}
}
1. PageController,負責操作、監聽 PageView
2. 引導頁要呈現的分頁資料
3. 當前分頁索引 currentPageIndex,判斷是否隱藏/顯示按鈕
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: tpiPrimaryColor,
// 疊放多個 Widget
body: Stack(
children: [
ScrollConfiguration(
behavior: ScrollBehavior(),
// 顯示多個頁面,讓用戶可以水平滑動瀏覽不同的分頁
child: PageView(
controller: controller,
children: list.map(
(page) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 270,
width: 230,
child: Image(
image: AssetImage(page.imagePath),
fit: BoxFit.contain),
),
48.height,
Text(page.title,
style: boldTextStyle(size: 24, color: whiteColor)),
16.height,
Text(
page.subtitle,
style: secondaryTextStyle(color: whiteColor),
textAlign: TextAlign.center,
),
],
).paddingAll(16.0);
},
).toList(),
onPageChanged: (index) {
setState(() {
currentPageIndex = index;
});
},
),
),
Positioned(
bottom: 30,
left: 16,
right: 16,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// 用於顯示分頁指示器,指示使用者當前處於哪個頁面
DotIndicator(pageController: controller, pages: list),
// 當用戶滑動到最後一頁時,顯示開始使用按鈕,其餘頁面則隱藏
Visibility(
visible: currentPageIndex == list.length - 1,
maintainState: true,
maintainAnimation: true,
maintainSize: true,
child: AppButton(
onTap: () {
return TPILoginScreen().launch(context);
},
color: white,
child: Text(tpiGetStarted,
style: boldTextStyle(color: tpiPrimaryColor)),
)),
],
),
),
Positioned(
top: 40,
right: 16,
// 當用戶滑動到最後一頁時,隱藏略過按鈕,其餘頁面則顯示
child: Visibility(
visible: currentPageIndex < list.length - 1,
child: Text(tpiSkip, style: boldTextStyle(color: whiteColor))
.paddingOnly(top: 8, right: 8)
.onTap(
() {
TPILoginScreen().launch(context);
},
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
splashColor: Colors.transparent,
),
),
),
],
),
);
}
1. 使用 Scaffold 作為頁面的骨架,包含了一個 Statck 來疊放多個 Widget
2. 使用 PageView 顯示多個頁面,讓用戶可以水平滑動瀏覽不同的分頁
3. 使用 DotIndicator 用於顯示分頁指示器,指示使用者當前處於哪個頁面
4. 透過 Visibility 控制顯示或隱藏按鈕
* 當用戶滑動到最後一頁時,顯示開始使用按鈕,其餘頁面則隱藏
* 當用戶滑動到最後一頁時,隱藏略過按鈕,其餘頁面則顯示
總結
本文範例展示了一個完整的 Flutter APP 引導畫面,使用 PageView 組件實現頁面瀏覽、滑動效果,並使用 DotIndicator 顯示當前頁面的指示器。提供略過按鈕,讓用戶可以直接進入註冊、登入畫面。
APP 引導頁能夠有效提升使用者體驗,並幫助新用戶快速了解 APP 的主要功能。