Flutter - 實作簡潔美觀的APP引導頁

Morgan Ko 2024/06/27 17:27:13
283

前言

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 的主要功能。

 

 

 

 

 

 

Morgan Ko