2 changed files with 547 additions and 23 deletions
@ -1,10 +1,537 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|||
import 'package:get/get.dart'; |
|||
|
|||
class MeetingMemberView extends StatelessWidget { |
|||
import '../../../profile/views/unified_avatar.dart'; |
|||
import '../../controllers/meeting_mine_controller.dart'; |
|||
import '../bottomSheet/member_bottom_sheet.dart'; |
|||
|
|||
class MeetingMemberView extends StatefulWidget { |
|||
const MeetingMemberView({super.key}); |
|||
|
|||
@override |
|||
State<MeetingMemberView> createState() => _MeetingMemberViewState(); |
|||
} |
|||
|
|||
class _MeetingMemberViewState extends State<MeetingMemberView> { |
|||
final _controller = Get.put(MeetingMineController()); |
|||
|
|||
int _tabsIndex = 0; |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return const Placeholder(); |
|||
return Scaffold( |
|||
backgroundColor: Colors.black, |
|||
appBar: _buildAppBar(), |
|||
body: _buildBody(), |
|||
); |
|||
} |
|||
|
|||
// 构建应用栏 |
|||
PreferredSizeWidget _buildAppBar() { |
|||
return AppBar( |
|||
backgroundColor: Colors.black, |
|||
surfaceTintColor: Colors.transparent, |
|||
elevation: 0.5, |
|||
leading: IconButton( |
|||
icon: Icon( |
|||
Icons.arrow_back_ios, |
|||
color: Colors.white, |
|||
size: 20.sp, |
|||
), |
|||
onPressed: () => Get.back(), |
|||
), |
|||
title: Text( |
|||
'VOITRANS AI会员', |
|||
style: TextStyle( |
|||
fontSize: 17.sp, |
|||
fontWeight: FontWeight.w600, |
|||
color: Colors.white, |
|||
), |
|||
), |
|||
centerTitle: true, |
|||
); |
|||
} |
|||
|
|||
Widget _buildBody() { |
|||
return Container( |
|||
padding: EdgeInsets.symmetric(horizontal: 12.w), |
|||
child: ListView( |
|||
children: [ |
|||
_head(), |
|||
_member(), |
|||
_tabs(), |
|||
_comparison(), |
|||
], |
|||
), |
|||
); |
|||
} |
|||
|
|||
Widget _head() { |
|||
return Padding( |
|||
padding: EdgeInsets.symmetric(vertical: 20.w), |
|||
child: Row( |
|||
children: [ |
|||
Container( |
|||
margin: EdgeInsets.only(right: 10.w), |
|||
child: UnifiedAvatar( |
|||
radius: 25.w, |
|||
backgroundColor: Colors.grey[200], |
|||
iconColor: Colors.grey[600], |
|||
iconSize: 25.r, |
|||
isDarkMode: true, |
|||
), |
|||
), |
|||
Expanded( |
|||
child: Obx( |
|||
() => Text( |
|||
_controller.profileCtrl.userInfo.value.name, |
|||
style: TextStyle( |
|||
color: Colors.white, |
|||
fontSize: 20.sp, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
); |
|||
} |
|||
|
|||
Widget _member() { |
|||
return GestureDetector( |
|||
onTap: () { |
|||
Get.bottomSheet( |
|||
const MemberBottomSheet(), |
|||
isScrollControlled: true, |
|||
backgroundColor: Colors.white, |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.vertical( |
|||
top: Radius.circular(12.r), |
|||
), |
|||
), |
|||
); |
|||
}, |
|||
child: Container( |
|||
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 15.w), |
|||
decoration: BoxDecoration( |
|||
color: const Color(0xFF1A1A1A), |
|||
borderRadius: BorderRadius.circular(16.w), |
|||
), |
|||
child: Column( |
|||
children: [ |
|||
Row( |
|||
children: [ |
|||
Icon( |
|||
Icons.auto_awesome, |
|||
color: Colors.amberAccent, |
|||
size: 25.sp, |
|||
), |
|||
5.horizontalSpace, |
|||
Text( |
|||
'解锁 Starter 会员', |
|||
style: TextStyle( |
|||
color: Colors.white, |
|||
fontSize: 18.sp, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
], |
|||
), |
|||
Padding( |
|||
padding: EdgeInsets.only(top: 15.w), |
|||
child: Row( |
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|||
children: [ |
|||
Text( |
|||
'绑定 Voitrans 设备可激活 Starter 会员', |
|||
style: TextStyle( |
|||
color: Colors.white, |
|||
fontSize: 12.sp, |
|||
), |
|||
), |
|||
Container( |
|||
padding: EdgeInsets.symmetric( |
|||
horizontal: 10.w, |
|||
vertical: 6.w, |
|||
), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(50.w), |
|||
gradient: const LinearGradient( |
|||
colors: [Colors.blue, Colors.pink], |
|||
begin: Alignment.centerLeft, |
|||
end: Alignment.centerRight, |
|||
), |
|||
), |
|||
child: Text( |
|||
'立即解锁', |
|||
style: TextStyle( |
|||
color: Colors.white, |
|||
fontSize: 14.sp, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
), |
|||
], |
|||
), |
|||
), |
|||
); |
|||
} |
|||
|
|||
Widget _tabs() { |
|||
return Container( |
|||
padding: EdgeInsets.all(2.w), |
|||
margin: EdgeInsets.only(top: 20.w, bottom: 5.w), |
|||
decoration: BoxDecoration( |
|||
color: Colors.grey[700], |
|||
borderRadius: BorderRadius.circular(10.w), |
|||
), |
|||
child: Row( |
|||
children: [ |
|||
Expanded( |
|||
child: GestureDetector( |
|||
onTap: () { |
|||
setState(() { |
|||
_tabsIndex = 0; |
|||
}); |
|||
}, |
|||
behavior: HitTestBehavior.translucent, |
|||
child: Container( |
|||
height: 30.w, |
|||
alignment: Alignment.center, |
|||
decoration: _tabsIndex == 0 |
|||
? BoxDecoration( |
|||
color: Colors.grey[50], |
|||
borderRadius: BorderRadius.circular(8.w), |
|||
) |
|||
: null, |
|||
child: Text( |
|||
'对比', |
|||
style: TextStyle( |
|||
color: _tabsIndex == 0 ? Colors.black : Colors.white, |
|||
fontSize: 14.sp, |
|||
fontWeight: _tabsIndex == 0 ? FontWeight.bold : null, |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
Expanded( |
|||
child: GestureDetector( |
|||
onTap: () { |
|||
setState(() { |
|||
_tabsIndex = 1; |
|||
}); |
|||
}, |
|||
behavior: HitTestBehavior.translucent, |
|||
child: Container( |
|||
height: 30.w, |
|||
alignment: Alignment.center, |
|||
decoration: _tabsIndex == 1 |
|||
? BoxDecoration( |
|||
color: Colors.grey[50], |
|||
borderRadius: BorderRadius.circular(8.w), |
|||
) |
|||
: null, |
|||
child: Text( |
|||
'详细信息', |
|||
style: TextStyle( |
|||
color: _tabsIndex == 1 ? Colors.black : Colors.white, |
|||
fontSize: 14.sp, |
|||
fontWeight: _tabsIndex == 1 ? FontWeight.bold : null, |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
); |
|||
} |
|||
|
|||
Widget _comparison() { |
|||
return Column( |
|||
children: [ |
|||
Container( |
|||
height: 50.w, |
|||
decoration: BoxDecoration( |
|||
border: Border( |
|||
bottom: BorderSide( |
|||
color: Colors.grey[700]!, |
|||
width: 0.5, |
|||
), |
|||
), |
|||
), |
|||
child: Row( |
|||
children: [ |
|||
const Expanded(child: SizedBox.square()), |
|||
Container( |
|||
width: 60.w, |
|||
alignment: Alignment.center, |
|||
child: Text( |
|||
'Starter', |
|||
style: TextStyle( |
|||
color: Colors.grey[200], |
|||
fontSize: 14.sp, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
), |
|||
Container( |
|||
width: 70.w, |
|||
alignment: Alignment.center, |
|||
child: Container( |
|||
width: 40.w, |
|||
height: 24.w, |
|||
alignment: Alignment.center, |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(8.w), |
|||
gradient: const LinearGradient( |
|||
colors: [Colors.blue, Colors.pink], |
|||
begin: Alignment.centerLeft, |
|||
end: Alignment.centerRight, |
|||
), |
|||
), |
|||
child: Text( |
|||
'Pro', |
|||
style: TextStyle( |
|||
color: Colors.white, |
|||
fontSize: 14.sp, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
), |
|||
), |
|||
Container( |
|||
width: 72.w, |
|||
alignment: Alignment.center, |
|||
child: Container( |
|||
width: 72.w, |
|||
height: 24.w, |
|||
alignment: Alignment.center, |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(8.w), |
|||
gradient: const LinearGradient( |
|||
colors: [ |
|||
Colors.amberAccent, |
|||
Colors.white, |
|||
Colors.amberAccent |
|||
], |
|||
begin: Alignment.centerLeft, |
|||
end: Alignment.centerRight, |
|||
), |
|||
), |
|||
child: Text( |
|||
'Unlimited', |
|||
style: TextStyle( |
|||
color: Colors.black, |
|||
fontSize: 14.sp, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
), |
|||
_tables( |
|||
'每月转写时长', |
|||
'300', |
|||
'1200', |
|||
'无限', |
|||
isGradient: true, |
|||
), |
|||
_tables( |
|||
'专业模版', |
|||
'有限', |
|||
'全量模版', |
|||
'全量模版', |
|||
), |
|||
_tables( |
|||
'专业术语', |
|||
'—', |
|||
'', |
|||
'', |
|||
), |
|||
_tables( |
|||
'自定义模版', |
|||
'—', |
|||
'', |
|||
'', |
|||
), |
|||
_tables( |
|||
'Ask AI', |
|||
'—', |
|||
'', |
|||
'', |
|||
), |
|||
_tables( |
|||
'可视化思维导图', |
|||
'', |
|||
'', |
|||
'', |
|||
), |
|||
_tables( |
|||
'区分说话人', |
|||
'', |
|||
'', |
|||
'', |
|||
), |
|||
_tables( |
|||
'Private Cloud Sync', |
|||
'', |
|||
'', |
|||
'', |
|||
), |
|||
_tables( |
|||
'AI 人声增强', |
|||
'', |
|||
'', |
|||
'', |
|||
), |
|||
_tables( |
|||
'音频导入', |
|||
'', |
|||
'', |
|||
'', |
|||
), |
|||
_tables( |
|||
'支持多种导出格式', |
|||
'', |
|||
'', |
|||
'', |
|||
), |
|||
], |
|||
); |
|||
} |
|||
|
|||
Widget _tables( |
|||
String title, |
|||
String starter, |
|||
String pro, |
|||
String unlimited, { |
|||
bool isGradient = false, |
|||
}) { |
|||
return Container( |
|||
height: 50.w, |
|||
decoration: BoxDecoration( |
|||
border: Border( |
|||
bottom: BorderSide( |
|||
color: Colors.grey[700]!, |
|||
width: 0.5, |
|||
), |
|||
), |
|||
), |
|||
child: Row( |
|||
children: [ |
|||
Expanded( |
|||
child: Text( |
|||
title, |
|||
style: TextStyle( |
|||
color: Colors.grey[200], |
|||
fontSize: 12.sp, |
|||
), |
|||
), |
|||
), |
|||
Container( |
|||
width: 60.w, |
|||
alignment: Alignment.center, |
|||
child: starter.isNotEmpty |
|||
? Text( |
|||
starter, |
|||
style: TextStyle( |
|||
color: Colors.grey[200], |
|||
fontSize: 12.sp, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
) |
|||
: _check(false), |
|||
), |
|||
Container( |
|||
width: 70.w, |
|||
alignment: Alignment.center, |
|||
child: pro.isNotEmpty |
|||
? isGradient |
|||
? ShaderMask( |
|||
shaderCallback: (bounds) => const LinearGradient( |
|||
colors: [Colors.blue, Colors.pink], |
|||
begin: Alignment.centerLeft, |
|||
end: Alignment.centerRight, |
|||
).createShader(bounds), |
|||
child: Text( |
|||
pro, |
|||
style: TextStyle( |
|||
color: Colors.white, |
|||
fontSize: 12.sp, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
) |
|||
: Text( |
|||
pro, |
|||
style: TextStyle( |
|||
color: Colors.white, |
|||
fontSize: 12.sp, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
) |
|||
: _check(isGradient), |
|||
), |
|||
Container( |
|||
width: 72.w, |
|||
alignment: Alignment.center, |
|||
child: unlimited.isNotEmpty |
|||
? ShaderMask( |
|||
shaderCallback: (bounds) => const LinearGradient( |
|||
colors: [ |
|||
Colors.amberAccent, |
|||
Colors.yellowAccent, |
|||
Colors.amberAccent, |
|||
], |
|||
begin: Alignment.centerLeft, |
|||
end: Alignment.centerRight, |
|||
).createShader(bounds), |
|||
child: Text( |
|||
unlimited, |
|||
style: TextStyle( |
|||
color: Colors.white, |
|||
fontSize: 12.sp, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
) |
|||
: _check(true), |
|||
), |
|||
], |
|||
), |
|||
); |
|||
} |
|||
|
|||
Widget _check(bool isGradient) { |
|||
return Container( |
|||
width: 20.w, |
|||
height: 20.w, |
|||
alignment: Alignment.center, |
|||
decoration: BoxDecoration( |
|||
color: Colors.grey[400], |
|||
borderRadius: BorderRadius.circular(20.w), |
|||
gradient: isGradient |
|||
? const LinearGradient( |
|||
colors: [Colors.amberAccent, Colors.white, Colors.amberAccent], |
|||
begin: Alignment.centerLeft, |
|||
end: Alignment.centerRight, |
|||
) |
|||
: null, |
|||
), |
|||
child: Icon( |
|||
Icons.check, |
|||
color: Colors.black, |
|||
size: 16.sp, |
|||
), |
|||
); |
|||
} |
|||
} |
|||
|
|||
Loading…
Reference in new issue