612 lines
22 KiB
Dart
612 lines
22 KiB
Dart
![]() |
import 'package:flutter/material.dart';
|
||
|
import 'package:flutter/services.dart';
|
||
|
import 'package:flutter_svg/svg.dart';
|
||
|
import 'package:get/get.dart';
|
||
|
import 'package:get/get_rx/src/rx_typedefs/rx_typedefs.dart';
|
||
|
import 'package:loopin/IM/im_service.dart';
|
||
|
import 'package:loopin/components/custom_sticky_header.dart';
|
||
|
import 'package:loopin/components/only_down_scroll_physics.dart';
|
||
|
import 'package:loopin/controller/video_module_controller.dart';
|
||
|
import 'package:nested_scroll_view_plus/nested_scroll_view_plus.dart';
|
||
|
import 'package:shirne_dialog/shirne_dialog.dart';
|
||
|
|
||
|
import '../../utils/common.dart';
|
||
|
|
||
|
class PageParams {
|
||
|
int page;
|
||
|
int pageSize;
|
||
|
bool isLoading;
|
||
|
bool hasMore;
|
||
|
|
||
|
PageParams({
|
||
|
this.page = 1,
|
||
|
this.pageSize = 10,
|
||
|
this.isLoading = false,
|
||
|
this.hasMore = true,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
class MyPage extends StatefulWidget {
|
||
|
const MyPage({super.key});
|
||
|
|
||
|
@override
|
||
|
State<MyPage> createState() => MyPageState();
|
||
|
}
|
||
|
|
||
|
class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
|
||
|
late RxInt currentTabIndex = 0.obs;
|
||
|
late RxList items = [].obs;
|
||
|
late RxList favoriteItems = [].obs;
|
||
|
late RxMap userInfo = {}.obs;
|
||
|
RxBool get shouldFixHeader => (currentTabIndex.value == 0 && items.isEmpty) || (currentTabIndex.value == 1 && favoriteItems.isEmpty) ? true.obs : false.obs;
|
||
|
|
||
|
List tabList = [
|
||
|
{'name': "作品", 'badge': 99},
|
||
|
{'name': "喜欢"},
|
||
|
];
|
||
|
|
||
|
late PageParams itemsParams;
|
||
|
late PageParams favoriteParams;
|
||
|
|
||
|
late TabController tabController;
|
||
|
late ScrollController scrollController;
|
||
|
|
||
|
late Callback tabListener;
|
||
|
late Callback scrollListener;
|
||
|
|
||
|
@override
|
||
|
void initState() {
|
||
|
super.initState();
|
||
|
itemsParams = PageParams();
|
||
|
favoriteParams = PageParams();
|
||
|
initControllers();
|
||
|
|
||
|
scrollListener = () {
|
||
|
final pos = scrollController.position;
|
||
|
final isNearBottom = pos.pixels >= pos.maxScrollExtent - 100;
|
||
|
|
||
|
if (!isNearBottom) return;
|
||
|
|
||
|
if (currentTabIndex.value == 0 && !itemsParams.isLoading && itemsParams.hasMore) {
|
||
|
loadData(0);
|
||
|
} else if (currentTabIndex.value == 1 && !favoriteParams.isLoading && favoriteParams.hasMore) {
|
||
|
loadData(1);
|
||
|
}
|
||
|
};
|
||
|
scrollController.addListener(scrollListener);
|
||
|
|
||
|
tabListener = () {
|
||
|
currentTabIndex.value = tabController.index;
|
||
|
scrollController.animateTo(0, duration: const Duration(milliseconds: 300), curve: Curves.easeIn);
|
||
|
if (tabController.index == 0 && items.isEmpty) {
|
||
|
loadData(0);
|
||
|
} else if (tabController.index == 1 && favoriteItems.isEmpty) {
|
||
|
loadData(1);
|
||
|
}
|
||
|
};
|
||
|
tabController.addListener(tabListener);
|
||
|
|
||
|
loadData(0);
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
void dispose() {
|
||
|
tabController.removeListener(tabListener);
|
||
|
scrollController.removeListener(scrollListener);
|
||
|
|
||
|
tabController.dispose();
|
||
|
scrollController.dispose();
|
||
|
super.dispose();
|
||
|
}
|
||
|
|
||
|
void loadData([int? tabIndex]) async {
|
||
|
final index = tabIndex ?? currentTabIndex.value;
|
||
|
if (index == 0) {
|
||
|
if (itemsParams.isLoading || !itemsParams.hasMore) return;
|
||
|
|
||
|
itemsParams.isLoading = true;
|
||
|
|
||
|
await Future.delayed(const Duration(seconds: 1));
|
||
|
|
||
|
// 模拟生成新数据
|
||
|
List<String> newItems = List.generate(
|
||
|
itemsParams.pageSize,
|
||
|
(i) => '作品 ${(itemsParams.page - 1) * itemsParams.pageSize + i + 1}',
|
||
|
);
|
||
|
|
||
|
// 模拟判断是否还有更多数据
|
||
|
if (itemsParams.page >= 2) {
|
||
|
itemsParams.hasMore = false;
|
||
|
}
|
||
|
|
||
|
// 添加新数据,触发响应式更新
|
||
|
items.addAll(newItems);
|
||
|
|
||
|
// 页码加一
|
||
|
itemsParams.page++;
|
||
|
|
||
|
itemsParams.isLoading = false;
|
||
|
} else if (index == 1) {
|
||
|
// 喜欢列表同理
|
||
|
if (favoriteParams.isLoading || !favoriteParams.hasMore) return;
|
||
|
|
||
|
favoriteParams.isLoading = true;
|
||
|
|
||
|
await Future.delayed(const Duration(seconds: 1));
|
||
|
|
||
|
List<String> newFavorites = List.generate(
|
||
|
favoriteParams.pageSize,
|
||
|
(i) => '喜欢 ${(favoriteParams.page - 1) * favoriteParams.pageSize + i + 1}',
|
||
|
);
|
||
|
|
||
|
if (favoriteParams.page >= 2) {
|
||
|
favoriteParams.hasMore = false;
|
||
|
}
|
||
|
|
||
|
favoriteItems.addAll(newFavorites);
|
||
|
|
||
|
favoriteParams.page++;
|
||
|
|
||
|
favoriteParams.isLoading = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void initControllers() {
|
||
|
tabController = TabController(initialIndex: 0, length: tabList.length, vsync: this);
|
||
|
scrollController = ScrollController();
|
||
|
}
|
||
|
|
||
|
// 初始化页面数据
|
||
|
void refreshData() {
|
||
|
if (!mounted) {
|
||
|
logger.i('未挂载');
|
||
|
return;
|
||
|
}
|
||
|
if (!Common.isLogin()) return;
|
||
|
itemsParams = PageParams();
|
||
|
favoriteParams = PageParams();
|
||
|
currentTabIndex.value = 0;
|
||
|
items.clear();
|
||
|
favoriteItems.clear();
|
||
|
scrollController.animateTo(0, duration: const Duration(milliseconds: 100), curve: Curves.easeIn);
|
||
|
selfInfo();
|
||
|
loadData();
|
||
|
}
|
||
|
|
||
|
// 获取当前登录用户基本信息
|
||
|
void selfInfo() async {
|
||
|
final resIm = await ImService.instance.selfInfo();
|
||
|
if (resIm.success) {
|
||
|
for (var user in resIm.data ?? []) {
|
||
|
logger.i(user.toLogString());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 二维码名片弹窗
|
||
|
void qrcodeAlertDialog(BuildContext context) {
|
||
|
showDialog(
|
||
|
context: context,
|
||
|
builder: (context) {
|
||
|
return UnconstrainedBox(
|
||
|
constrainedAxis: Axis.vertical,
|
||
|
child: SizedBox(
|
||
|
width: 350.0,
|
||
|
child: AlertDialog(
|
||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
|
||
|
backgroundColor: const Color(0xff07c160),
|
||
|
surfaceTintColor: Colors.white,
|
||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)),
|
||
|
content: Padding(
|
||
|
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||
|
child: Column(
|
||
|
mainAxisSize: MainAxisSize.min,
|
||
|
children: [
|
||
|
Image.asset('assets/images/pic1.jpg', width: 250.0, fit: BoxFit.contain),
|
||
|
const SizedBox(height: 15.0),
|
||
|
const Text('扫一扫,加好友',
|
||
|
style: TextStyle(
|
||
|
color: Colors.white38,
|
||
|
fontSize: 14.0,
|
||
|
)),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
);
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// 退出登录弹窗
|
||
|
void showLogoutDialog(BuildContext context) {
|
||
|
showDialog(
|
||
|
context: context,
|
||
|
builder: (context) {
|
||
|
return AlertDialog(
|
||
|
content: const Text('确认退出当前账号吗?', style: TextStyle(fontSize: 16.0)),
|
||
|
backgroundColor: Colors.white,
|
||
|
surfaceTintColor: Colors.white,
|
||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)),
|
||
|
elevation: 2.0,
|
||
|
actionsPadding: const EdgeInsets.all(15.0),
|
||
|
actions: [
|
||
|
TextButton(
|
||
|
onPressed: () {
|
||
|
Get.back();
|
||
|
},
|
||
|
child: const Text('取消', style: TextStyle(color: Colors.black54)),
|
||
|
),
|
||
|
TextButton(onPressed: handleLogout, child: const Text('退出登录', style: TextStyle(color: Colors.red))),
|
||
|
],
|
||
|
);
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// 退出登录
|
||
|
void handleLogout() async {
|
||
|
final loginRes = await ImService.instance.logout();
|
||
|
if (loginRes.success) {
|
||
|
// 清除存储信息
|
||
|
Common.logout();
|
||
|
// 初始化视频
|
||
|
final videoController = Get.find<VideoModuleController>();
|
||
|
videoController.init();
|
||
|
Get.back();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
return Scaffold(
|
||
|
backgroundColor: const Color(0xFFFAF6F9),
|
||
|
body: Obx(() {
|
||
|
return NestedScrollViewPlus(
|
||
|
controller: scrollController,
|
||
|
physics: shouldFixHeader.value ? const OnlyDownScrollPhysics(parent: AlwaysScrollableScrollPhysics()) : const AlwaysScrollableScrollPhysics(),
|
||
|
overscrollBehavior: OverscrollBehavior.outer,
|
||
|
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
||
|
return [
|
||
|
SliverAppBar(
|
||
|
backgroundColor: Colors.transparent,
|
||
|
surfaceTintColor: Colors.transparent,
|
||
|
expandedHeight: 180.0,
|
||
|
collapsedHeight: 120.0,
|
||
|
pinned: true,
|
||
|
stretch: true,
|
||
|
onStretchTrigger: () async {
|
||
|
logger.i('触发 stretch 拉伸');
|
||
|
// 加载刷新逻辑
|
||
|
},
|
||
|
actions: [
|
||
|
_buildIcon('assets/images/svg/service.svg', () {
|
||
|
logger.i('点击客服按钮');
|
||
|
}),
|
||
|
const SizedBox(width: 8.0),
|
||
|
_buildIcon('assets/images/svg/setting.svg', () {
|
||
|
logger.i('点击设置按钮');
|
||
|
}),
|
||
|
const SizedBox(width: 10.0),
|
||
|
],
|
||
|
flexibleSpace: _buildFlexibleSpace(),
|
||
|
),
|
||
|
SliverToBoxAdapter(
|
||
|
child: Padding(
|
||
|
padding: const EdgeInsets.all(10.0),
|
||
|
child: Column(
|
||
|
children: [
|
||
|
_buildStatsCard(),
|
||
|
const SizedBox(height: 10.0),
|
||
|
_buildOrderCard(context),
|
||
|
const SizedBox(height: 10.0),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
SliverPersistentHeader(
|
||
|
pinned: true,
|
||
|
delegate: CustomStickyHeader(
|
||
|
child: PreferredSize(
|
||
|
preferredSize: const Size.fromHeight(48.0),
|
||
|
child: Container(
|
||
|
color: Colors.white,
|
||
|
child: TabBar(
|
||
|
controller: tabController,
|
||
|
tabs: tabList.map((item) {
|
||
|
return Tab(
|
||
|
child: Badge.count(
|
||
|
backgroundColor: Colors.red,
|
||
|
count: item['badge'] ?? 0,
|
||
|
isLabelVisible: item['badge'] != null,
|
||
|
alignment: Alignment.topRight,
|
||
|
offset: const Offset(14, -6),
|
||
|
child: Text(item['name'], style: const TextStyle(fontWeight: FontWeight.bold)),
|
||
|
),
|
||
|
);
|
||
|
}).toList(),
|
||
|
isScrollable: false,
|
||
|
overlayColor: WidgetStateProperty.all(Colors.transparent),
|
||
|
unselectedLabelColor: Colors.black87,
|
||
|
labelColor: const Color(0xFFFF5000),
|
||
|
indicator: const UnderlineTabIndicator(borderSide: BorderSide(color: Color(0xFFFF5000), width: 2.0)),
|
||
|
indicatorSize: TabBarIndicatorSize.tab,
|
||
|
unselectedLabelStyle: const TextStyle(fontSize: 16.0, fontFamily: 'Microsoft YaHei'),
|
||
|
labelStyle: const TextStyle(fontSize: 18.0, fontFamily: 'Microsoft YaHei', fontWeight: FontWeight.bold),
|
||
|
dividerHeight: 0,
|
||
|
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||
|
labelPadding: const EdgeInsets.symmetric(horizontal: 15.0),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
];
|
||
|
},
|
||
|
body: TabBarView(
|
||
|
controller: tabController,
|
||
|
children: [
|
||
|
// Tab 1:
|
||
|
Obx(() => _buildGridTab(0)),
|
||
|
|
||
|
// Tab 2:
|
||
|
Obx(() => _buildGridTab(1))
|
||
|
],
|
||
|
),
|
||
|
);
|
||
|
}),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// 空状态提示
|
||
|
Widget emptyTip(String text) {
|
||
|
return CustomScrollView(
|
||
|
physics: const OnlyDownScrollPhysics(),
|
||
|
slivers: [
|
||
|
SliverFillRemaining(
|
||
|
hasScrollBody: false,
|
||
|
child: Align(
|
||
|
alignment: Alignment.topCenter,
|
||
|
child: Padding(
|
||
|
padding: const EdgeInsets.only(top: 50.0),
|
||
|
child: Column(
|
||
|
mainAxisSize: MainAxisSize.min,
|
||
|
children: [
|
||
|
Image.asset('assets/images/empty.png', width: 100.0),
|
||
|
const SizedBox(height: 8.0),
|
||
|
Text(
|
||
|
text,
|
||
|
style: const TextStyle(color: Colors.grey, fontSize: 13.0),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
);
|
||
|
}
|
||
|
|
||
|
Widget _buildGridTab(int tabIndex) {
|
||
|
final listToShow = tabIndex == 0 ? items : favoriteItems;
|
||
|
final params = tabIndex == 0 ? itemsParams : favoriteParams;
|
||
|
|
||
|
if (listToShow.isEmpty) {
|
||
|
return emptyTip('暂无相关数据');
|
||
|
}
|
||
|
|
||
|
return CustomScrollView(
|
||
|
slivers: [
|
||
|
SliverPadding(
|
||
|
padding: const EdgeInsets.all(10.0),
|
||
|
sliver: SliverGrid(
|
||
|
delegate: SliverChildBuilderDelegate(
|
||
|
(context, index) {
|
||
|
return Container(
|
||
|
decoration: BoxDecoration(
|
||
|
color: Colors.blue[100 * ((index % 8) + 1)],
|
||
|
borderRadius: BorderRadius.circular(10.0),
|
||
|
),
|
||
|
alignment: Alignment.center,
|
||
|
child: Text(listToShow[index], style: const TextStyle(fontWeight: FontWeight.bold)),
|
||
|
);
|
||
|
},
|
||
|
childCount: listToShow.length,
|
||
|
),
|
||
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||
|
crossAxisCount: 3,
|
||
|
crossAxisSpacing: 10.0,
|
||
|
mainAxisSpacing: 10.0,
|
||
|
childAspectRatio: 1.0,
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
SliverToBoxAdapter(
|
||
|
child: Padding(
|
||
|
padding: const EdgeInsets.symmetric(vertical: 20.0),
|
||
|
child: Center(
|
||
|
child: params.hasMore ? const CircularProgressIndicator() : const Text('没有更多数据了'),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
);
|
||
|
}
|
||
|
|
||
|
Widget _buildIcon(String assetPath, VoidCallback onTap) {
|
||
|
return InkWell(
|
||
|
onTap: onTap,
|
||
|
child: Container(
|
||
|
padding: const EdgeInsets.symmetric(horizontal: 5.0, vertical: 5.0),
|
||
|
decoration: BoxDecoration(color: Colors.black.withAlpha((0.3 * 255).round()), borderRadius: BorderRadius.circular(20.0)),
|
||
|
child: SvgPicture.asset(assetPath, height: 20.0, width: 20.0, colorFilter: const ColorFilter.mode(Colors.white70, BlendMode.srcIn)),
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
Widget _buildFlexibleSpace() {
|
||
|
return LayoutBuilder(
|
||
|
builder: (BuildContext context, BoxConstraints constraints) {
|
||
|
final double maxHeight = 180.0;
|
||
|
final double minHeight = 100.0;
|
||
|
final double currentHeight = constraints.maxHeight;
|
||
|
double ratio = (currentHeight - minHeight) / (maxHeight - minHeight);
|
||
|
ratio = ratio.clamp(0.0, 1.0);
|
||
|
|
||
|
return Stack(
|
||
|
fit: StackFit.expand,
|
||
|
children: [
|
||
|
Positioned.fill(child: Opacity(opacity: 1.0, child: Image.asset('assets/images/pic2.jpg', fit: BoxFit.cover))),
|
||
|
Positioned(
|
||
|
left: 15.0,
|
||
|
bottom: 0,
|
||
|
right: 15.0,
|
||
|
child: Container(
|
||
|
padding: const EdgeInsets.symmetric(vertical: 10.0),
|
||
|
child: Row(
|
||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||
|
children: <Widget>[
|
||
|
ClipOval(child: Image.asset('assets/images/avatar/img11.jpg', height: 60.0, width: 60.0, fit: BoxFit.cover)),
|
||
|
const SizedBox(width: 15.0),
|
||
|
Expanded(
|
||
|
child: Column(
|
||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||
|
children: [
|
||
|
Row(
|
||
|
children: [
|
||
|
Container(
|
||
|
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
|
||
|
decoration: BoxDecoration(color: Colors.black.withAlpha((0.3 * 255).round()), borderRadius: BorderRadius.circular(20.0)),
|
||
|
child: const Text(
|
||
|
'新用户2025',
|
||
|
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold, fontFamily: 'Arial', color: Colors.white),
|
||
|
),
|
||
|
),
|
||
|
const SizedBox(width: 8.0),
|
||
|
InkWell(
|
||
|
onTap: () {
|
||
|
qrcodeAlertDialog(context);
|
||
|
},
|
||
|
child: Container(
|
||
|
padding: const EdgeInsets.symmetric(horizontal: 5.0, vertical: 5.0),
|
||
|
decoration: BoxDecoration(color: Colors.black.withAlpha((0.3 * 255).round()), borderRadius: BorderRadius.circular(20.0)),
|
||
|
child: const Icon(Icons.qr_code_outlined, size: 18.0, color: Colors.white),
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
const SizedBox(height: 8.0),
|
||
|
Container(
|
||
|
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
|
||
|
decoration: BoxDecoration(color: Colors.black.withAlpha((0.3 * 255).round()), borderRadius: BorderRadius.circular(20.0)),
|
||
|
child: InkWell(
|
||
|
onTap: () {
|
||
|
logger.i('点击个人简介');
|
||
|
Clipboard.setData(const ClipboardData(text: '1234'));
|
||
|
MyDialog.toast('ID已复制', icon: const Icon(Icons.check_circle), style: ToastStyle(backgroundColor: Colors.green.withAlpha(200)));
|
||
|
},
|
||
|
child: const Text('ID:32938293892839232', style: TextStyle(fontSize: 12.0, color: Colors.white)),
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
);
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
|
||
|
Widget _buildStatsCard() {
|
||
|
return Container(
|
||
|
decoration: BoxDecoration(
|
||
|
color: Colors.white,
|
||
|
borderRadius: BorderRadius.circular(15.0),
|
||
|
boxShadow: [BoxShadow(color: Colors.black.withAlpha(10), offset: const Offset(0.0, 1.0), blurRadius: 2.0, spreadRadius: 0.0)],
|
||
|
),
|
||
|
clipBehavior: Clip.antiAlias,
|
||
|
child: Padding(
|
||
|
padding: const EdgeInsets.all(10.0),
|
||
|
child: Row(
|
||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||
|
children: [
|
||
|
Column(children: const [Text('9999', style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), SizedBox(height: 3.0), Text('获赞')]),
|
||
|
Column(children: const [Text('25', style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), SizedBox(height: 3.0), Text('互关')]),
|
||
|
Column(children: const [Text('11', style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), SizedBox(height: 3.0), Text('关注')]),
|
||
|
Column(children: const [Text('10', style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), SizedBox(height: 3.0), Text('粉丝')]),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
Widget _buildOrderCard(BuildContext context) {
|
||
|
return Container(
|
||
|
decoration: BoxDecoration(
|
||
|
color: Colors.white,
|
||
|
borderRadius: BorderRadius.circular(15.0),
|
||
|
boxShadow: [BoxShadow(color: Colors.black.withAlpha(10), offset: const Offset(0.0, 1.0), blurRadius: 2.0, spreadRadius: 0.0)],
|
||
|
),
|
||
|
clipBehavior: Clip.antiAlias,
|
||
|
child: Column(
|
||
|
children: [
|
||
|
GestureDetector(
|
||
|
child: Container(
|
||
|
padding: const EdgeInsets.all(10.0),
|
||
|
child: Row(
|
||
|
children: [
|
||
|
Row(
|
||
|
children: [
|
||
|
Image.asset('assets/images/more.png', width: 16.0),
|
||
|
const SizedBox(width: 5.0),
|
||
|
const Text('常用功能', style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold)),
|
||
|
],
|
||
|
),
|
||
|
const Spacer(),
|
||
|
const Text('全部', style: TextStyle(color: Colors.grey, fontSize: 12.0)),
|
||
|
const Icon(Icons.arrow_forward_ios_rounded, color: Colors.grey, size: 12.0),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
onTap: () {},
|
||
|
),
|
||
|
Padding(
|
||
|
padding: const EdgeInsets.all(10.0),
|
||
|
child: Row(
|
||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||
|
children: [
|
||
|
_buildOrderIcon('assets/images/ico_order.png', '订单', () {
|
||
|
Get.toNamed('/order');
|
||
|
}),
|
||
|
_buildOrderIcon('assets/images/ico_dhx.png', '余额', () {
|
||
|
showLogoutDialog(context);
|
||
|
}),
|
||
|
_buildOrderIcon('assets/images/ico_sh.png', '提现', () {}),
|
||
|
_buildOrderIcon('assets/images/ico_tgm.png', '推广码', () {}),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
Widget _buildOrderIcon(String assetPath, String label, VoidCallback onTap) {
|
||
|
return GestureDetector(
|
||
|
onTap: onTap,
|
||
|
child: Column(
|
||
|
children: [
|
||
|
Image.asset(assetPath, width: 24.0),
|
||
|
const SizedBox(height: 3.0),
|
||
|
Text(label),
|
||
|
],
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
}
|