feat: 增加侧滑事件
This commit is contained in:
@@ -13,76 +13,86 @@ import 'package:kaer_with_panels/app/widgets/hi_collapsible_list.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/hi_fixed_scrollbar.dart';
|
||||
import 'package:kaer_with_panels/app/modules/hi_menu/widgets/hi_menu_list_item.dart';
|
||||
import '../../../routes/app_pages.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/swipe/has_swipe_config.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/swipe/swipe_config.dart';
|
||||
|
||||
class HIHelpView extends GetView<HIHelpController> {
|
||||
class HIHelpView extends GetView<HIHelpController> implements HasSwipeConfig {
|
||||
const HIHelpView({super.key});
|
||||
|
||||
@override
|
||||
SwipeConfig get swipeConfig =>
|
||||
SwipeConfig(enableLeft: true, onLeft: () => Get.back());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
|
||||
return HIBaseScaffold(
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Obx(
|
||||
() => EasyRefresh(
|
||||
// controller: controller.refreshController,
|
||||
// onRefresh: controller.kr_onRefresh,
|
||||
// onLoad: controller.kr_onLoadMore,
|
||||
// header: const DeliveryHeader(
|
||||
// triggerOffset: 50.0,
|
||||
// springRebound: true,
|
||||
// ),
|
||||
// footer: const DeliveryFooter(
|
||||
// triggerOffset: 50.0,
|
||||
// springRebound: true,
|
||||
// ),
|
||||
onRefresh: null, // 设置为 null 来禁用下拉刷新
|
||||
onLoad: null, // 设置为 null 来禁用上拉加载
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(right: 0.w), // 滚动条与内容间距
|
||||
child: HiFixedScrollbar(
|
||||
controller: scrollController,
|
||||
child: ListView.builder(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Obx(
|
||||
() => EasyRefresh(
|
||||
// controller: controller.refreshController,
|
||||
// onRefresh: controller.kr_onRefresh,
|
||||
// onLoad: controller.kr_onLoadMore,
|
||||
// header: const DeliveryHeader(
|
||||
// triggerOffset: 50.0,
|
||||
// springRebound: true,
|
||||
// ),
|
||||
// footer: const DeliveryFooter(
|
||||
// triggerOffset: 50.0,
|
||||
// springRebound: true,
|
||||
// ),
|
||||
onRefresh: null, // 设置为 null 来禁用下拉刷新
|
||||
onLoad: null, // 设置为 null 来禁用上拉加载
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(right: 0.w), // 滚动条与内容间距
|
||||
child: HiFixedScrollbar(
|
||||
controller: scrollController,
|
||||
padding: EdgeInsets.symmetric(horizontal: 40.w),
|
||||
itemCount: controller.kr_messages.length,
|
||||
itemBuilder: (context, index) {
|
||||
final message = controller.kr_messages[index];
|
||||
final collapsibleItemData = HICollapsibleItem(
|
||||
title: message.title,
|
||||
content: message.content,
|
||||
);
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(bottom: 10.w),
|
||||
child: HICollapsibleItemWidget(item: collapsibleItemData),
|
||||
);
|
||||
},
|
||||
child: ListView.builder(
|
||||
controller: scrollController,
|
||||
padding: EdgeInsets.only(left: 40.w - 20, right: 40.w),
|
||||
itemCount: controller.kr_messages.length,
|
||||
itemBuilder: (context, index) {
|
||||
final message = controller.kr_messages[index];
|
||||
final collapsibleItemData = HICollapsibleItem(
|
||||
title: message.title,
|
||||
content: message.content,
|
||||
);
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(bottom: 10.w),
|
||||
child: HICollapsibleItemWidget(
|
||||
item: collapsibleItemData),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 60.w),
|
||||
// 增加在线客服入口
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 40.w),
|
||||
child: MenuListItem(
|
||||
// 2. 创建一个 MenuItem 数据对象
|
||||
item: MenuItem(
|
||||
iconName: 'icon-5',
|
||||
title: '在线客服',
|
||||
// 3. 使用 onTap 回调来处理跳转逻辑
|
||||
onTap: () {
|
||||
Get.toNamed(Routes.KR_CRISP);
|
||||
},
|
||||
SizedBox(height: 60.w),
|
||||
// 增加在线客服入口
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 40.w),
|
||||
child: MenuListItem(
|
||||
// 2. 创建一个 MenuItem 数据对象
|
||||
item: MenuItem(
|
||||
iconName: 'icon-5',
|
||||
title: '在线客服',
|
||||
// 3. 使用 onTap 回调来处理跳转逻辑
|
||||
onTap: () {
|
||||
Get.toNamed(Routes.KR_CRISP);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 30.w)
|
||||
],
|
||||
SizedBox(height: 30.w)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import 'package:flutter_html/flutter_html.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/hi_base_scaffold.dart';
|
||||
import '../../../routes/app_pages.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/swipe/has_swipe_config.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/swipe/swipe_config.dart';
|
||||
import '../controllers/hi_menu_controller.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/kr_app_text_style.dart';
|
||||
import 'package:kaer_with_panels/app/localization/app_translations.dart';
|
||||
@@ -16,9 +18,15 @@ import 'package:kaer_with_panels/app/common/app_run_data.dart';
|
||||
import 'package:kaer_with_panels/app/modules/hi_menu/widgets/hi_menu_list_item.dart';
|
||||
import 'package:kaer_with_panels/app/modules/hi_menu/widgets/user_info_card.dart';
|
||||
|
||||
class HIMenuView extends GetView<HIMenuController> {
|
||||
class HIMenuView extends GetView<HIMenuController> implements HasSwipeConfig {
|
||||
const HIMenuView({super.key});
|
||||
|
||||
@override
|
||||
SwipeConfig get swipeConfig => SwipeConfig(
|
||||
enableRight: true,
|
||||
onRight: () => Get.offNamed(Routes.KR_HOME),
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return HIBaseScaffold(
|
||||
@@ -37,9 +45,13 @@ class HIMenuView extends GetView<HIMenuController> {
|
||||
mainAxisSize: MainAxisSize.min, // 让 Column 包裹内容
|
||||
children: [
|
||||
Obx(() {
|
||||
final account = KRAppRunData.getInstance().kr_account.value;
|
||||
final isDeviceLogin = account != null && account.startsWith('9000');
|
||||
final accountText = (account ==null || isDeviceLogin) ? '待绑定' : '${KRAppRunData.getInstance().kr_account.value.toString()}';
|
||||
final account =
|
||||
KRAppRunData.getInstance().kr_account.value;
|
||||
final isDeviceLogin =
|
||||
account != null && account.startsWith('9000');
|
||||
final accountText = (account == null || isDeviceLogin)
|
||||
? '待绑定'
|
||||
: '${KRAppRunData.getInstance().kr_account.value.toString()}';
|
||||
return UserInfoCard(
|
||||
controller: controller,
|
||||
userId: accountText,
|
||||
@@ -51,7 +63,8 @@ class HIMenuView extends GetView<HIMenuController> {
|
||||
// ListView.separated 现在也会继承 Padding 的约束
|
||||
ListView.separated(
|
||||
shrinkWrap: true, // 让 ListView 高度自适应内容
|
||||
physics: const NeverScrollableScrollPhysics(), // 在 Stack 中,禁用其自身的滚动
|
||||
physics:
|
||||
const NeverScrollableScrollPhysics(), // 在 Stack 中,禁用其自身的滚动
|
||||
itemCount: _menuItems.length,
|
||||
// 渲染每一项
|
||||
itemBuilder: (context, index) {
|
||||
@@ -68,7 +81,7 @@ class HIMenuView extends GetView<HIMenuController> {
|
||||
],
|
||||
),
|
||||
// 版本号信息
|
||||
Obx((){
|
||||
Obx(() {
|
||||
// 1. 从 Obx 的回调函数中 return 一个 Widget
|
||||
return Positioned(
|
||||
bottom: 40.0,
|
||||
@@ -91,7 +104,6 @@ class HIMenuView extends GetView<HIMenuController> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const List<MenuItem> _menuItems = [
|
||||
MenuItem(
|
||||
iconName: 'icon-1',
|
||||
@@ -118,4 +130,4 @@ const List<MenuItem> _menuItems = [
|
||||
title: '在线客服',
|
||||
route: Routes.KR_CRISP,
|
||||
),
|
||||
];
|
||||
];
|
||||
|
||||
@@ -18,8 +18,22 @@ import 'kr_home_subscription_view.dart';
|
||||
import './hi_animated_connect_button.dart';
|
||||
import 'package:kaer_with_panels/app/services/global_overlay_service.dart';
|
||||
|
||||
class KRHomeView extends StatefulWidget {
|
||||
import 'package:kaer_with_panels/app/widgets/swipe/has_swipe_config.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/swipe/swipe_config.dart';
|
||||
import 'package:kaer_with_panels/app/routes/app_pages.dart';
|
||||
|
||||
class KRHomeView extends StatefulWidget implements HasSwipeConfig {
|
||||
const KRHomeView({super.key});
|
||||
@override
|
||||
SwipeConfig get swipeConfig => SwipeConfig(
|
||||
enableLeft: true,
|
||||
enableRight: true,
|
||||
onLeft: () {
|
||||
Get.toNamed(Routes.HI_MENU);
|
||||
},
|
||||
onRight: () =>
|
||||
GlobalOverlayService.instance.triggerSubscriptionAnimation(),
|
||||
);
|
||||
|
||||
@override
|
||||
State<KRHomeView> createState() => _KRHomeViewState();
|
||||
|
||||
@@ -47,7 +47,7 @@ class KRLoginView extends GetView<KRLoginController> {
|
||||
SizedBox(height: 20.w),
|
||||
_buildUserInfoSection(),
|
||||
SizedBox(height: 12.w),
|
||||
_buildContentByEntry(),
|
||||
_buildBindEmailLayout(),
|
||||
SizedBox(height: 100.w), // 为底部帮助按钮留出空间
|
||||
],
|
||||
),
|
||||
|
||||
@@ -13,93 +13,104 @@ import 'package:kaer_with_panels/app/widgets/hi_help_entrance.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/hi_collapsible_list.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/hi_fixed_scrollbar.dart';
|
||||
import '../../../widgets/kr_simple_loading.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/swipe/has_swipe_config.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/swipe/swipe_config.dart';
|
||||
|
||||
class KRMessageView extends GetView<KRMessageController> {
|
||||
class KRMessageView extends GetView<KRMessageController>
|
||||
implements HasSwipeConfig {
|
||||
const KRMessageView({super.key});
|
||||
|
||||
@override
|
||||
SwipeConfig get swipeConfig =>
|
||||
SwipeConfig(enableLeft: true, onLeft: () => Get.back());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
|
||||
return HIBaseScaffold(
|
||||
child: Stack(
|
||||
children: [
|
||||
// 主要内容区域
|
||||
Obx(() {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(bottom: 90.w),
|
||||
child: EasyRefresh(
|
||||
controller: controller.refreshController,
|
||||
onRefresh: controller.kr_onRefresh,
|
||||
onLoad: controller.kr_onLoadMore,
|
||||
header: ClassicHeader(
|
||||
dragText: '下拉刷新',
|
||||
armedText: '释放刷新',
|
||||
readyText: '正在刷新...',
|
||||
processingText: '正在刷新...',
|
||||
processedText: '刷新成功',
|
||||
failedText: '刷新失败',
|
||||
messageText: '最后更新于 %T',
|
||||
textStyle:
|
||||
TextStyle(color: Colors.white.withOpacity(0.7)),
|
||||
messageStyle: TextStyle(
|
||||
color: Colors.white.withOpacity(0.5),
|
||||
fontSize: 12.sp),
|
||||
iconTheme:
|
||||
IconThemeData(color: Colors.white.withOpacity(0.7)),
|
||||
),
|
||||
footer: ClassicFooter(
|
||||
dragText: '上拉加载',
|
||||
armedText: '释放加载',
|
||||
readyText: '正在加载...',
|
||||
processingText: '正在加载...',
|
||||
processedText: '加载成功',
|
||||
failedText: '加载失败',
|
||||
noMoreText: '没有更多数据了',
|
||||
messageText: '最后更新于 %T',
|
||||
textStyle:
|
||||
TextStyle(color: Colors.white.withOpacity(0.7)),
|
||||
messageStyle: TextStyle(
|
||||
color: Colors.white.withOpacity(0.5),
|
||||
fontSize: 12.sp),
|
||||
iconTheme:
|
||||
IconThemeData(color: Colors.white.withOpacity(0.7)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(right: 0.w),
|
||||
child: HiFixedScrollbar(
|
||||
controller: scrollController,
|
||||
child: ListView.builder(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
child: Stack(
|
||||
children: [
|
||||
// 主要内容区域
|
||||
Obx(() {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(bottom: 90.w),
|
||||
child: EasyRefresh(
|
||||
controller: controller.refreshController,
|
||||
onRefresh: controller.kr_onRefresh,
|
||||
onLoad: controller.kr_onLoadMore,
|
||||
header: ClassicHeader(
|
||||
dragText: '下拉刷新',
|
||||
armedText: '释放刷新',
|
||||
readyText: '正在刷新...',
|
||||
processingText: '正在刷新...',
|
||||
processedText: '刷新成功',
|
||||
failedText: '刷新失败',
|
||||
messageText: '最后更新于 %T',
|
||||
textStyle:
|
||||
TextStyle(color: Colors.white.withOpacity(0.7)),
|
||||
messageStyle: TextStyle(
|
||||
color: Colors.white.withOpacity(0.5),
|
||||
fontSize: 12.sp),
|
||||
iconTheme: IconThemeData(
|
||||
color: Colors.white.withOpacity(0.7)),
|
||||
),
|
||||
footer: ClassicFooter(
|
||||
dragText: '上拉加载',
|
||||
armedText: '释放加载',
|
||||
readyText: '正在加载...',
|
||||
processingText: '正在加载...',
|
||||
processedText: '加载成功',
|
||||
failedText: '加载失败',
|
||||
noMoreText: '没有更多数据了',
|
||||
messageText: '最后更新于 %T',
|
||||
textStyle:
|
||||
TextStyle(color: Colors.white.withOpacity(0.7)),
|
||||
messageStyle: TextStyle(
|
||||
color: Colors.white.withOpacity(0.5),
|
||||
fontSize: 12.sp),
|
||||
iconTheme: IconThemeData(
|
||||
color: Colors.white.withOpacity(0.7)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(right: 0.w),
|
||||
child: HiFixedScrollbar(
|
||||
controller: scrollController,
|
||||
padding: EdgeInsets.symmetric(horizontal: 40.w),
|
||||
itemCount: controller.kr_messages.length,
|
||||
itemBuilder: (context, index) {
|
||||
final message = controller.kr_messages[index];
|
||||
final collapsibleItemData = HICollapsibleItem(
|
||||
title: message.title,
|
||||
content: [message.content],
|
||||
);
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(bottom: 10.w),
|
||||
child: HICollapsibleItemWidget(
|
||||
item: collapsibleItemData),
|
||||
);
|
||||
},
|
||||
child: ListView.builder(
|
||||
controller: scrollController,
|
||||
padding:
|
||||
EdgeInsets.only(left: 40.w - 20, right: 40.w),
|
||||
itemCount: controller.kr_messages.length,
|
||||
itemBuilder: (context, index) {
|
||||
final message = controller.kr_messages[index];
|
||||
final collapsibleItemData = HICollapsibleItem(
|
||||
title: message.title,
|
||||
content: [message.content],
|
||||
);
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(bottom: 10.w),
|
||||
child: HICollapsibleItemWidget(
|
||||
item: collapsibleItemData),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
// 底部帮助入口
|
||||
const HIHelpEntrance(),
|
||||
],
|
||||
],
|
||||
);
|
||||
}),
|
||||
// 底部帮助入口
|
||||
const HIHelpEntrance(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,12 +14,19 @@ import '../../../widgets/kr_network_image.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/dialogs/kr_dialog.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/kr_local_image.dart';
|
||||
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/swipe/has_swipe_config.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/swipe/swipe_config.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
/// 购买会员页面视图
|
||||
class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
||||
class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController>
|
||||
implements HasSwipeConfig {
|
||||
const KRPurchaseMembershipView({super.key});
|
||||
|
||||
@override
|
||||
SwipeConfig get swipeConfig =>
|
||||
SwipeConfig(enableLeft: true, onLeft: () => Get.back());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return HIBaseScaffold(
|
||||
@@ -27,106 +34,129 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
||||
title: '套餐选择',
|
||||
subtitle: '*所有套餐均不限流量不限速度',
|
||||
topContentAreaHeight: 110,
|
||||
child: Obx(() {
|
||||
return Stack(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 80.0),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
/*_kr_buildAccountSection(context),*/
|
||||
if (controller.kr_isLoading.value)
|
||||
Container(
|
||||
height: MediaQuery.of(context).size.height * 0.5,
|
||||
child: Center(
|
||||
child: KRSimpleLoading(
|
||||
color: Colors.white,
|
||||
size: 50.0,
|
||||
),
|
||||
),
|
||||
)
|
||||
else if (controller.kr_plans.isEmpty)
|
||||
Container(
|
||||
height: MediaQuery.of(context).size.height * 0.5,
|
||||
child: Center(
|
||||
child: Text(
|
||||
AppTranslations.kr_purchaseMembership.noData,
|
||||
style: KrAppTextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium
|
||||
?.color,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 40.0),
|
||||
child: Column(
|
||||
children: [
|
||||
// 套餐选择部分
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
left: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
width: 20,
|
||||
child: const _LeftEdgeSwipeBack(),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
child: Stack(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 80.0),
|
||||
child: Obx(() => SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
/*_kr_buildAccountSection(context),*/
|
||||
if (controller.kr_isLoading.value)
|
||||
Container(
|
||||
padding: EdgeInsets.all(0.0),
|
||||
height:
|
||||
MediaQuery.of(context).size.height * 0.5,
|
||||
child: Center(
|
||||
child: KRSimpleLoading(
|
||||
color: Colors.white,
|
||||
size: 50.0,
|
||||
),
|
||||
),
|
||||
)
|
||||
else if (controller.kr_plans.isEmpty)
|
||||
Container(
|
||||
height:
|
||||
MediaQuery.of(context).size.height * 0.5,
|
||||
child: Center(
|
||||
child: Text(
|
||||
AppTranslations
|
||||
.kr_purchaseMembership.noData,
|
||||
style: KrAppTextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium
|
||||
?.color,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: 40.0 - 20, right: 40.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
// 使用 List.generate 动态创建卡片列表
|
||||
children: List.generate(
|
||||
controller.kr_getTotalOptionsCount(
|
||||
controller.kr_plans[controller
|
||||
.kr_selectedPlanIndex.value]),
|
||||
(index) {
|
||||
final plan = controller.kr_plans[
|
||||
controller
|
||||
.kr_selectedPlanIndex.value];
|
||||
final discountIndex =
|
||||
plan.kr_discount.isEmpty
|
||||
? null
|
||||
: index;
|
||||
// 使用 Padding 来为每个卡片添加底部的间距,模拟 mainAxisSpacing
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.only(bottom: 8.0),
|
||||
child: SizedBox(
|
||||
height: 130.0,
|
||||
child: _kr_buildPlanOptionCard(
|
||||
plan,
|
||||
controller
|
||||
.kr_selectedPlanIndex.value,
|
||||
discountIndex,
|
||||
context,
|
||||
index,
|
||||
),
|
||||
// 套餐选择部分
|
||||
Container(
|
||||
padding: EdgeInsets.all(0.0),
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
// 使用 List.generate 动态创建卡片列表
|
||||
children: List.generate(
|
||||
controller.kr_getTotalOptionsCount(
|
||||
controller.kr_plans[controller
|
||||
.kr_selectedPlanIndex
|
||||
.value]),
|
||||
(index) {
|
||||
final plan = controller
|
||||
.kr_plans[
|
||||
controller
|
||||
.kr_selectedPlanIndex
|
||||
.value];
|
||||
final discountIndex =
|
||||
plan.kr_discount.isEmpty
|
||||
? null
|
||||
: index;
|
||||
// 使用 Padding 来为每个卡片添加底部的间距,模拟 mainAxisSpacing
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: 8.0),
|
||||
child: SizedBox(
|
||||
height: 130.0,
|
||||
child:
|
||||
_kr_buildPlanOptionCard(
|
||||
plan,
|
||||
controller
|
||||
.kr_selectedPlanIndex
|
||||
.value,
|
||||
discountIndex,
|
||||
context,
|
||||
index,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
Positioned(
|
||||
top: 160.0, // 距离顶部的距离
|
||||
right: 10.0, // 固定在右侧 20.w 的位置
|
||||
child: KrLocalImage(
|
||||
imageName: 'purchase_slogan',
|
||||
imageType: ImageType.svg,
|
||||
),
|
||||
)),
|
||||
Positioned(
|
||||
top: 160.0, // 距离顶部的距离
|
||||
right: 10.0, // 固定在右侧 20.w 的位置
|
||||
child: KrLocalImage(
|
||||
imageName: 'purchase_slogan',
|
||||
imageType: ImageType.svg,
|
||||
),
|
||||
),
|
||||
const HIHelpEntrance(isLight: false)
|
||||
],
|
||||
),
|
||||
const HIHelpEntrance(isLight: false)
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -328,3 +358,47 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _LeftEdgeSwipeBack extends StatefulWidget {
|
||||
const _LeftEdgeSwipeBack();
|
||||
@override
|
||||
State<_LeftEdgeSwipeBack> createState() => _LeftEdgeSwipeBackState();
|
||||
}
|
||||
|
||||
class _LeftEdgeSwipeBackState extends State<_LeftEdgeSwipeBack> {
|
||||
Offset? _start;
|
||||
Offset? _last;
|
||||
DateTime? _startTime;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onHorizontalDragStart: (details) {
|
||||
_start = details.globalPosition;
|
||||
_startTime = DateTime.now();
|
||||
KRLogUtil.kr_d(
|
||||
'Purchase left edge dragStart x=${details.globalPosition.dx}',
|
||||
tag: 'PurchaseSwipe');
|
||||
},
|
||||
onHorizontalDragUpdate: (details) {
|
||||
_last = details.globalPosition;
|
||||
},
|
||||
onHorizontalDragEnd: (details) {
|
||||
final durationMs = DateTime.now()
|
||||
.difference(_startTime ?? DateTime.now())
|
||||
.inMilliseconds;
|
||||
final distance =
|
||||
_last != null && _start != null ? (_last!.dx - _start!.dx) : 0.0;
|
||||
KRLogUtil.kr_d(
|
||||
'Purchase left edge dragEnd dur=$durationMs dist=$distance',
|
||||
tag: 'PurchaseSwipe');
|
||||
if (distance > 20) {
|
||||
Get.back();
|
||||
}
|
||||
_start = null;
|
||||
_last = null;
|
||||
_startTime = null;
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user