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.27搭建项目框架,使用Vscode编码开发调试。
目前flutter3-trip酒店预订app项目已经同步到我的作品集,感谢大家的鼓励与支持~
https://gf.bilibili.com/item/detail/1107864011
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应用的一些知识分享,整个项目知识点还是蛮多的,希望上述分享对大家有所帮助!最后感谢大家的阅读与支持~
附上几个原创跨平台项目实例
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
flutter3-trip仿携程酒店预订|Flutter3.27+Getx预约旅游酒店App程序的更多相关文章
- 【仿携程JQuery日期价格表】
今天比较闲所以就花点时间又写了点东西. 相信这种价格表大家不会陌生 现在我就模仿它做一个简单版本的.效果如下 首先需要两个时间控件,我这里用的是HTML5里面的时间控件,这个没限制喜欢用什么就用什么 ...
- Android 仿携程活动列表边框布局
实现如下图所示的一个页面布局 布局框架 思路讲解: 1.一开始的思路是使用android提供的画布将布局中的内容花下来,之后想了想觉得比较麻烦,所以又开启了另外一条思路. 2.如上图“布局框架”所示. ...
- 携程实时大数据平台演进:1/3 Storm应用已迁到JStorm
携程大数据平台负责人张翼分享携程的实时大数据平台的迭代,按照时间线介绍采用的技术以及踩过的坑.携程最初基于稳定和成熟度选择了Storm+Kafka,解决了数据共享.资源控制.监控告警.依赖管理等问题之 ...
- [转] 携程App网络服务通道治理和性能优化@2016
App网络服务的高可靠和低延迟对于无线业务稳定发展至关重要,过去两年来我们一直在持续优化App网络服务的性能,到今年Q2结束时基本完成了App网络服务通道治理和性能优化的阶段性目标,特此撰文总结其中的 ...
- 微信小程序体验(1):携程酒店机票火车票
在 12 月 28 日微信公开课上,张小龙对微信小程序的形态进行了阐释,小程序有四个特定:无需安装.触手可及.用完即走.无需卸载. 由于携程这种订酒店.火车票和机票等工具性质非常强的服务,非常符合张小 ...
- 使用requests、re、BeautifulSoup、线程池爬取携程酒店信息并保存到Excel中
import requests import json import re import csv import threadpool import time, random from bs4 impo ...
- 携程酒店DevOps测试实践
作者简介 王幸福,携程酒店研发部高级测试经理,负责无线自动化测试相关工作.在测试框架和平台研发.移动测试.DevOps等领域有着丰富的经验. 如今很多大型互联网公司.创新型企业都在积极地进行DevOp ...
- html5——伸缩比例案例(携程)
1.有图片的盒子,最好是父盒子设置伸缩属性,a标签设置伸缩比例1,img标签宽度100% 2.不要见到父盒子就设置伸缩属性,而是根据子盒子是否占据一行,若是子盒子占据一行,那么只要给子盒子设置伸缩比例 ...
- 携程App的网络性能优化实践
首先介绍一下携程App的网络服务架构.由于携程业务众多,开发资源导致无法全部使用Native来实现业务逻辑,因此有相当一部分频道基于Hybrid实现.网络通讯属于基础&业务框架层中基础设施的一 ...
- 今天携程出事了:让我们来学习下http的响应码
就在今天,2015年5月28日,中国最大的旅游机票预订网站--携程网粗大事了.据传携程网的数据库被人物理删除了,而容灾备份的数据又无法正常使用,服务器全面遭受瘫痪.每小时给携程带来的损失约100万美元 ...
随机推荐
- HarmonyOS Next 入门实战 - 创建项目、主题适配
开发一个简单的demo,其中涉及一些鸿蒙应用开发的知识点,其中涉及导航框架,常用组件,列表懒加载,动画,深色模式适配,关系型数据库等内容,在实践中学习和熟悉鸿蒙应用开发. 首先下载并安装 ...
- openwrt交换机配置命令-swconfig
swconfig swconfig 是交换接口 (switch) 配置命令. 交换机是二层设备,是我们用来配置vlan的必备利器. 使用swconfig list可以列出当前可用的 SWITCH 设备 ...
- 04C++顺序结构(3)
一.设置域宽setw() 教学视频1 输出的内容所占的总宽度成为域宽,有些高级语言中称为场宽.使用setw()前,必须包含头文件iomanip,即#include.头文件iomanip,用来声明一些& ...
- NATS: Aspire.NATS.Net 库
NuGet Aspire.NATS.Net 快速入门 首先,你需要已经配置了 NATS 服务器,并且知道访问这个服务器的 URL 地址. 安装 NuGet 使用你熟悉的方式安装 NuGet 库 dot ...
- 在 Azure AI Studio 中创建项目并使用聊天演练场
在 Azure AI Studio 中创建项目并使用聊天演练场 See: Create a project and use the chat playground in Azure AI Studio ...
- PG 实现 Dynamic SQL
CREATE OR REPLACE FUNCTION public.exec( text) RETURNS SETOF RECORD LANGUAGE 'plpgsql' AS $BODY$ BEGI ...
- 序列化与反序列化的概念、基于django原生编写5个接口、drf介绍和快速使用、cbv源码分析
目录 一.序列化反序列化 二.基于django原生编写5个接口 三.drf介绍和快速使用 概念 安装 代码 四.cbv源码分析 一.序列化反序列化 api接口开发,最核心最常见的一个过程就是序列化,所 ...
- 【Python】HTML中Base64存储的图片转为本地图片文件
我用jupyter notebook写了笔记之后,想导出markdown,然后导出不了,我就只能导出html,结果导出的html存储图片用的base64的方式-- 于是我就要把导出的html文档里面的 ...
- 『AutoHotkey』 效率提升「脚本集」
AutoHotkey 效率提升脚本集 一些实用的 AutoHotkey 脚本示例,这些可以显著提升工作效率. #Requires AutoHotkey v2.0 ; 1. 快速启动常用程序 ^!n:: ...
- 基于高德地图API在Python中实现地图功能的方法
本文介绍在高德开放平台中,申请.获取地图API的Key的方法:同时通过简单的Python代码,调取API信息,对所得Key的可用性加以验证. 首先,我们进入高德开放平台的官方网站.如果大家是第 ...