動態

詳情 返回 返回

flutter3-trip仿攜程酒店預訂|Flutter3.27+Getx預約旅遊酒店App程序 - 動態 詳情

基於Flutter3.x+Dart3+GetX跨平台仿攜程/飛豬旅行酒店客房預訂查詢app系統。

flutter3_trip原創2025新版flutter3.27.1+dart3.6+getx+flutter_datepicker跨平台仿攜程/飛豬/同程旅遊app酒店客房預訂系統。實現了首頁、酒店預訂模塊、酒店搜索/列表/詳情、探索動態、訂單、消息聊天、我的等模塊。

技術棧

  • 編輯器:Vscode
  • 技術框架:Flutter3.27.1+Dart3.6.0
  • 路由/狀態管理:get: ^4.6.6
  • 本地緩存:get_storage: ^2.1.1
  • 圖片輪播組件:card_swiper^3.0.1
  • 日期選擇插件:syncfusion_flutter_datepicker^28.2.5
  • 彈層提示:shirne_dialog^4.8.3
  • 瀑布流組件:flutter_staggered_grid_view^0.7.0
  • 滾動定位組件:scrollable_positioned_list^0.3.8

分享幾個之前基於flutter3.x跨平台實戰項目案例,感興趣的可以去看看~

flutter3-dymall仿抖音直播商城|Flutter3.27短視頻+直播+聊天App實例

flutter3-winchat桌面端聊天實例|Flutter3+Dart3+Getx仿微信Exe程序

flutter3+dart3聊天室|Flutter3跨平台仿微信App語音聊天/朋友圈

酒店預訂模塊實現了城市地址/位置品牌選擇、入住離店日期區間選擇、價格/星級篩選等功能。

項目框架結構

基於最新跨平台框架Flutter3.27搭建項目框架,使用Vscode編碼開發調試。

目前flutter3-trip酒店預訂app項目已經同步到我的作品集,感謝大家的鼓勵與支持~

flutter3.27+getx仿攜程app旅行酒店預訂系統

Flutter3入口配置main.dart

/// 入口文件main.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:shirne_dialog/shirne_dialog.dart';

import 'utils/common.dart';

// 引入佈局頁面
import 'layouts/index.dart';

// 引入路由配置
import 'router/index.dart';

void main() async {
  // 初始化get_storage存儲
  await GetStorage.init();
  // 初始化國際化語言
  initializeDateFormatting('zh_CN');
  
  runApp(const App());
}

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter3 Trip',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Color(0xFF006ff6)),
        useMaterial3: true,
        // 修正windows下字體不一致情況
        fontFamily: Platform.isWindows ? 'Microsoft YaHei' : null
      ),
      home: const Layout(),
      // 初始化路由
      initialRoute: Common.isLogin() ? '/' : '/login',
      // 路由頁面
      getPages: routePages,
      // 初始化彈窗key
      navigatorKey: MyDialog.navigatorKey,
    );
  }
}

flutter3自定義滾動指示槽

 如上圖:首頁的分類滾動指示槽採用 SingleChildScrollView 配置 Stack 組件實現功能。

late ScrollController indicatorController = ScrollController();
// 滾動位置
double indicatorOffset = 0;

@override
void initState() {
  super.initState();
  indicatorController.addListener(() {
    setState(() {
      indicatorOffset = indicatorController.position.pixels / indicatorController.position.maxScrollExtent;
    });
  });
  ...
}

Column(
  children: [
    Expanded(
      child: SingleChildScrollView(
        controller: indicatorController,
        scrollDirection: Axis.horizontal,
        child: Row(
          ...
        ),
      ),
    ),
    // 指示槽
    Stack(
      children: [
        Container(
          decoration: BoxDecoration(
            color: Color(0xFFE1EFFF),
            borderRadius: BorderRadius.circular(50.0),
          ),
          height: 4.0,
          width: 50.0,
        ),
        Container(
          margin: EdgeInsets.only(left: indicatorOffset * 30.0),
          decoration: BoxDecoration(
            color: Color(0xFF006ff6),
            borderRadius: BorderRadius.circular(50.0),
          ),
          width: 20.0,
          height: 4.0,
        ),
      ],
    ),
  ],
),

flutter3實現酒店預訂模塊

由於預訂模塊功能點比較多,單獨抽離了一個組件。

預訂模塊支持熱門城市/位置品牌選擇、入住離店日期區間、價格/星級等功能。

如上圖:使用了 scrollable_positioned_list 組件實現滑動字母索引滾動到指定列表位置。

ItemScrollController itemScrollController = ItemScrollController();

ScrollablePositionedList.builder(
  itemScrollController: itemScrollController,
  itemCount: citylist.length,
  itemBuilder: (context, index) {
    // ...
  }
)

// 側邊索引
Align(
  alignment: Alignment.centerRight,
  child: GestureDetector(
    child: Container(
      color: Colors.transparent,
      width: 25.0,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.center,
        children: List.generate(pinyinList.length, (index) {
          return GestureDetector(
            child: Container(
              ...
            ),
            onTapDown: (details) {
              // 跳轉指定索引位置
              itemScrollController.jumpTo(index: index);
              setState(() {
                selectedLetter = pinyinList[index];
                showBubble = true;
              });
              Future.delayed(Duration(milliseconds: 200), () {
                setState(() {
                  selectedLetter = '';
                  showBubble = false;
                });
              });
            },
          );
        }),
      ),
    ),
    onVerticalDragUpdate: (details) {
      updateSelectedLetter(details.localPosition);
    },
    onVerticalDragEnd: (details) {
      setState(() {
        selectedLetter = '';
        showBubble = false;
      });
    },
  ),
),

日期區間選擇使用 syncfusion_flutter_datepicker 插件。

// 入住日期
DateTime startDate = DateTime.now();
// 離店日期
DateTime endDate = DateTime.now().add(Duration(days: 1));

GestureDetector(
  child: Container(
    padding: EdgeInsets.all(10.0),
    decoration: BoxDecoration(
      border: Border(bottom: BorderSide(color: Color(0xfff5f5f5))),
    ),
    child: Row(
      spacing: 10.0,
      children: [
        Icon(Icons.calendar_month_outlined),
        Expanded(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                spacing: 3.0,
                children: [
                  Text('入住', style: TextStyle(color: Colors.grey, fontSize: 12.0)),
                  Text('${DateFormat('MM-dd').format(startDate)} ${DateFormat('E', 'zh_CN').format(startDate)}'),
                ],
              ),
              Container(
                color: Colors.grey[50],
                padding: EdgeInsets.symmetric(horizontal: 5.0, vertical: 1.0),
                // DateTime 類提供了 difference 方法,可以計算兩個日期之間的時間差,返回一個 Duration 對象。通過 Duration 的 inDays 屬性,可以獲取天數差。
                child: Text('共${endDate.difference(startDate).inDays}晚'),
              ),
              Column(
                crossAxisAlignment: CrossAxisAlignment.end,
                spacing: 3.0,
                children: [
                  Text('離店', style: TextStyle(color: Colors.grey, fontSize: 12.0)),
                  Text('${DateFormat('MM-dd').format(endDate)} ${DateFormat('E', 'zh_CN').format(endDate)}'),
                ],
              ),
            ],
          ),
        ),
        Icon(Icons.arrow_forward_ios_rounded, color: Colors.grey, size: 12.0,)
      ],
    ),
  ),
  onTap: () {
    handleCalendar();
  },
),
void handleCalendar() {
  showModalBottomSheet(
    backgroundColor: Colors.white,
    shape: RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(0.0))),
    context: context,
    builder: (BuildContext context) {
      return Column(
        children: [
          Expanded(
            child: SfDateRangePicker(
              selectionMode: DateRangePickerSelectionMode.range,
              selectionShape: DateRangePickerSelectionShape.rectangle,
              // 初始日期範圍
              initialSelectedRange: PickerDateRange(startDate, endDate),
              minDate: DateTime.now(),
              maxDate: DateTime.now().add(Duration(days: 450)),
              backgroundColor: Colors.white,
              // 日期區間顏色
              startRangeSelectionColor: Color(0xFF006ff6),
              endRangeSelectionColor: Color(0xFF006ff6),
              rangeSelectionColor: Color(0xFFe3f0f9),
              // 選中顏色
              selectionColor: Color(0xFF006ff6),
              rangeTextStyle: TextStyle(color: Color(0xFF006ff6)),
              monthViewSettings: DateRangePickerMonthViewSettings(
                // 改變一週的第一天
                firstDayOfWeek: 1,
                viewHeaderStyle: DateRangePickerViewHeaderStyle(
                  textStyle: TextStyle(color: Color(0xFF130438), fontSize: 12, fontFamily: 'Arial'),
                ),
                dayFormat: 'EE',
              ),
              // 自定義頭部樣式
              headerStyle: DateRangePickerHeaderStyle(
                backgroundColor: Colors.white,
                textAlign: TextAlign.center
              ),
              // 日期單元格樣式
              monthCellStyle: DateRangePickerMonthCellStyle(
                cellDecoration: BoxDecoration(
                  // color: Color(0xFFf7f4ff),
                ),
                todayTextStyle: TextStyle(color: Color(0xFF006ff6)),
                disabledDatesTextStyle: TextStyle(color: Colors.black26),
                weekendTextStyle: TextStyle(color: Colors.red.withAlpha(200)),
              ),
              // showTodayButton: true,
              // showActionButtons: true,
              onSelectionChanged: (DateRangePickerSelectionChangedArgs args) {
                setState(() {
                  if(args.value.startDate != null && args.value.endDate != null) {
                    startDate = args.value.startDate;
                    endDate = args.value.endDate;
                    Future.delayed(Duration(seconds: 1), () {
                      Get.back();
                    });
                  }
                });
              },
            ),
          ),
        ],
      );
    },
  );
}

flutter3實現酒店列表篩選功能

篩選下拉框採用自定義組件實現功能,搭配 SizeTransition 和 FadeTransition 組件實現下拉動畫效果。

// 篩選下拉框
if(dropdownVisible)
Positioned(
  top: dropdownOffset,
  height: MediaQuery.of(context).size.height - dropdownOffset,
  width: MediaQuery.of(context).size.width,
  child: ScrollConfiguration(
    behavior: CustomScrollBehavior(),
    child: Material(
      color: Colors.transparent,
      child: Column(
        children: [
          SizeTransition(
            sizeFactor: animation, // 高度展開動畫
            axis: Axis.vertical, // 垂直方向展開
            child: Container(
              color: Colors.white,
              width: double.infinity,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  if(dropdownIndex == 0)
                  dropOption1(),
                  if(dropdownIndex == 1)
                  dropOption2(),
                  if(dropdownIndex == 2)
                  dropOption3(),
                  if(dropdownIndex == 3)
                  dropOption4(),
                ],
              ),
            ),
          ),
          Expanded(
            child: FadeTransition(
              opacity: animation,
              child: GestureDetector(
                child: Container(
                  color: Colors.black54,
                ),
                onTap: () {
                  setState(() {
                    closeDropdown();
                  });
                },
              ),
            ),
          ),
        ],
      ),
    ),
  ),
),

flutter3聊天客服消息模塊

項目整合進了flutter3實現聊天功能模塊。

  

flutter3+dart3聊天室|Flutter3跨平台仿微信App語音聊天/朋友圈

項目中新增的消息聊天模塊。這部分功能是之前開發的一款flutter3.x仿微信app聊天功能的精簡版。

綜上就是Flutter3.27跨平台實戰攜程酒店預訂app應用的一些知識分享,整個項目知識點還是蠻多的,希望上述分享對大家有所幫助!最後感謝大家的閲讀與支持~

flutter3-deepseek流式AI模板|Flutter3.27+Dio+DeepSeeek聊天ai助手

Uniapp-DeepSeek跨三端AI助手|uniapp+vue3+deepseek-v3流式ai聊天模板

vue3-webseek網頁版AI問答|Vite6+DeepSeek+Arco流式ai聊天打字效果

附上幾個原創跨平台項目實例

uniapp+vue3聊天室|uni-app+vite4+uv-ui跨端仿微信app聊天語音/朋友圈

Electron32-ViteOS桌面版os系統|vue3+electron+arco客户端OS管理模板

flutter3-dymall仿抖音直播商城|Flutter3.27短視頻+直播+聊天App實例

flutter3-winchat桌面端聊天實例|Flutter3+Dart3+Getx仿微信Exe程序

Electron31-Vue3Admin管理系統|vite5+electron+pinia桌面端後台Exe

Vite5+Electron聊天室|electron31跨平台仿微信EXE客户端|vue3聊天程序

uniapp+vue3酒店預訂|vite5+uniapp預約訂房系統模板(h5+小程序+App端)

user avatar hubert-style 頭像 HarmonyOS5 頭像 shu_5b5b4cde7027a 頭像 ducafecat 頭像 hhsk 頭像 mybj123 頭像
點贊 6 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.