Browse Source

排版首页和直播页

master
YakumoChen 5 months ago
parent
commit
60280c5f52
26 changed files with 707 additions and 130 deletions
  1. BIN
      assets/H.png
  2. BIN
      assets/chat.png
  3. BIN
      assets/chat_active.png
  4. BIN
      assets/friend.png
  5. BIN
      assets/friend_active.png
  6. BIN
      assets/home_top_active.png
  7. BIN
      assets/i.png
  8. BIN
      assets/index.png
  9. BIN
      assets/index_active.png
  10. BIN
      assets/location_icon.png
  11. BIN
      assets/my.png
  12. BIN
      assets/my_active.png
  13. BIN
      assets/pic1.png
  14. BIN
      assets/pic2.png
  15. BIN
      assets/pic3.png
  16. BIN
      assets/real_name.png
  17. BIN
      assets/subscript.png
  18. BIN
      assets/user_avatar.png
  19. 74
      lib/components/home_appbar.dart
  20. 2
      lib/components/page_appbar.dart
  21. 5
      lib/main.dart
  22. 62
      lib/pages/home_page.dart
  23. 394
      lib/pages/index_page.dart
  24. 268
      lib/pages/live_page.dart
  25. 2
      pubspec.yaml
  26. 30
      test/widget_test.dart

BIN
assets/H.png

Before After
Width: 39  |  Height: 44  |  Size: 370 B

BIN
assets/chat.png

Before After
Width: 124  |  Height: 124  |  Size: 1.9 KiB

BIN
assets/chat_active.png

Before After
Width: 124  |  Height: 124  |  Size: 3.1 KiB

BIN
assets/friend.png

Before After
Width: 124  |  Height: 124  |  Size: 1.9 KiB

BIN
assets/friend_active.png

Before After
Width: 124  |  Height: 124  |  Size: 4.0 KiB

BIN
assets/home_top_active.png

Before After
Width: 63  |  Height: 20  |  Size: 433 B

BIN
assets/i.png

Before After
Width: 12  |  Height: 44  |  Size: 274 B

BIN
assets/index.png

Before After
Width: 131  |  Height: 131  |  Size: 2.0 KiB

BIN
assets/index_active.png

Before After
Width: 131  |  Height: 131  |  Size: 3.4 KiB

BIN
assets/location_icon.png

Before After
Width: 25  |  Height: 29  |  Size: 375 B

BIN
assets/my.png

Before After
Width: 124  |  Height: 124  |  Size: 1.7 KiB

BIN
assets/my_active.png

Before After
Width: 124  |  Height: 124  |  Size: 3.9 KiB

BIN
assets/pic1.png

Before After
Width: 330  |  Height: 330  |  Size: 214 KiB

BIN
assets/pic2.png

Before After
Width: 330  |  Height: 330  |  Size: 186 KiB

BIN
assets/pic3.png

Before After
Width: 330  |  Height: 330  |  Size: 255 KiB

BIN
assets/real_name.png

Before After
Width: 32  |  Height: 28  |  Size: 461 B

BIN
assets/subscript.png

Before After
Width: 218  |  Height: 65  |  Size: 697 B

BIN
assets/user_avatar.png

Before After
Width: 232  |  Height: 232  |  Size: 79 KiB

74
lib/components/home_appbar.dart

@ -0,0 +1,74 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class HomeAppbar extends StatefulWidget {
final List<String> topNav;
final void Function(int) changeNav;
const HomeAppbar({super.key, required this.topNav, required this.changeNav});
@override
State<HomeAppbar> createState() => _HomeAppbarState();
}
class _HomeAppbarState extends State<HomeAppbar> {
int active = 0;
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
child: Container(
height: ScreenUtil().setWidth(108),
padding: EdgeInsets.symmetric(
horizontal: ScreenUtil().setWidth(34)),
child: Stack(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
...widget.topNav.asMap().entries.map((entry){
return InkWell(
onTap: (){
active = entry.key;
widget.changeNav(active);
setState(() {
});
},
child: Container(
margin: EdgeInsets.symmetric(horizontal: ScreenUtil().setWidth(27)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
entry.value,
style: TextStyle(
fontSize: active == entry.key ? 38.w : 34.w,
color: const Color.fromRGBO(51, 51, 51, 1),
fontWeight: active == entry.key ? FontWeight.w600 : FontWeight.w400
),
),
SizedBox(height: ScreenUtil().setWidth(9),),
if(active == entry.key) Image.asset(
"assets/home_top_active.png",
width: ScreenUtil().setWidth(25),
)
],
),
),
);
}),
],
)
],
),
),
);
}
}

2
lib/components/page_appbar.dart

@ -19,7 +19,7 @@ class PageAppbar extends StatelessWidget implements PreferredSizeWidget {
title: Text(
title,
style: TextStyle(
fontSize: ScreenUtil().setWidth(16),
fontSize: ScreenUtil().setWidth(32),
fontWeight: FontWeight.bold,
color: color
),

5
lib/main.dart

@ -8,9 +8,10 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
final appRouter = AppRouter();
runApp(MyApp(routerConfig: appRouter.router,));
runApp(MyApp(routerConfig: appRouter.router));
}
class MyApp extends StatefulWidget {
@ -39,7 +40,7 @@ class _MyAppState extends State<MyApp> {
],
//ui尺寸
child: ScreenUtilInit(
designSize: const Size(375, 667),
designSize: const Size(750, 1334),
builder: (context, child){
return MaterialApp.router(
theme: ThemeData(

62
lib/pages/home_page.dart

@ -17,12 +17,10 @@ class _HomePageState extends State<HomePage> {
int active = 1;
String title = "首页";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PageAppbar(title: title,),
body: Column(
children: [
Expanded(
@ -40,7 +38,7 @@ class _HomePageState extends State<HomePage> {
bottomNavigationBar: Container(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
child: SizedBox(
height: ScreenUtil().setWidth(50),
height: ScreenUtil().setWidth(100),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -49,7 +47,6 @@ class _HomePageState extends State<HomePage> {
child: InkWell(
onTap: (){
active = 1;
title = "首页";
setState(() {
});
@ -57,16 +54,16 @@ class _HomePageState extends State<HomePage> {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.home,
size: ScreenUtil().setWidth(26),
color: active == 1 ? const Color.fromRGBO(208, 116, 67, 1) : const Color.fromRGBO(208, 205, 216, 1)
Image.asset(
"assets/${active == 1 ? "index_active" : "index"}.png",
width: 65.w,
height: 65.w,
),
Text(
"首页",
"动我",
style: TextStyle(
fontSize: ScreenUtil().setWidth(12),
color: active == 1 ? const Color.fromRGBO(208, 116, 67, 1) : const Color.fromRGBO(208, 205, 216, 1)
fontSize: 16.w,
color: const Color.fromRGBO(51, 51, 51, 1)
),
)
],
@ -77,7 +74,6 @@ class _HomePageState extends State<HomePage> {
child: InkWell(
onTap: (){
active = 2;
title = "直播";
setState(() {
});
@ -85,16 +81,16 @@ class _HomePageState extends State<HomePage> {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.home,
size: ScreenUtil().setWidth(26),
color: active == 2 ? const Color.fromRGBO(208, 116, 67, 1) : const Color.fromRGBO(208, 205, 216, 1)
Image.asset(
"assets/${active == 2 ? "friend_active" : "friend"}.png",
width: 65.w,
height: 65.w,
),
Text(
"直播",
"找朋友",
style: TextStyle(
fontSize: ScreenUtil().setWidth(12),
color: active == 2 ? const Color.fromRGBO(208, 116, 67, 1) : const Color.fromRGBO(208, 205, 216, 1)
fontSize: 16.w,
color: const Color.fromRGBO(51, 51, 51, 1)
),
)
],
@ -105,7 +101,6 @@ class _HomePageState extends State<HomePage> {
child: InkWell(
onTap: (){
active = 3;
title = "信息";
setState(() {
});
@ -113,16 +108,16 @@ class _HomePageState extends State<HomePage> {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.home,
size: ScreenUtil().setWidth(26),
color: active == 3 ? const Color.fromRGBO(208, 116, 67, 1) : const Color.fromRGBO(208, 205, 216, 1)
Image.asset(
"assets/${active == 3 ? "chat_active" : "chat"}.png",
width: 65.w,
height: 65.w,
),
Text(
"",
"",
style: TextStyle(
fontSize: ScreenUtil().setWidth(12),
color: active == 3 ? const Color.fromRGBO(208, 116, 67, 1) : const Color.fromRGBO(208, 205, 216, 1)
fontSize: 16.w,
color: const Color.fromRGBO(51, 51, 51, 1)
),
)
],
@ -133,7 +128,6 @@ class _HomePageState extends State<HomePage> {
child: InkWell(
onTap: (){
active = 4;
title = "我的";
setState(() {
});
@ -141,16 +135,16 @@ class _HomePageState extends State<HomePage> {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.home,
size: ScreenUtil().setWidth(26),
color: active == 4 ? const Color.fromRGBO(208, 116, 67, 1) : const Color.fromRGBO(208, 205, 216, 1)
Image.asset(
"assets/${active == 4 ? "my_active" : "my"}.png",
width: 65.w,
height: 65.w,
),
Text(
"我的",
style: TextStyle(
fontSize: ScreenUtil().setWidth(12),
color: active == 4 ? const Color.fromRGBO(208, 116, 67, 1) : const Color.fromRGBO(208, 205, 216, 1)
fontSize: 16.w,
color: const Color.fromRGBO(51, 51, 51, 1)
),
)
],

394
lib/pages/index_page.dart

@ -1,3 +1,4 @@
import 'package:dating_touchme_app/components/home_appbar.dart';
import 'package:dating_touchme_app/components/page_appbar.dart';
import 'package:dating_touchme_app/config/app_config.dart';
import 'package:dating_touchme_app/http/api.dart';
@ -27,6 +28,20 @@ class _IndexPageState extends State<IndexPage> {
int num = 0;
List<Map> userList = [
{"isOnline": true, "isLive": false, "hasPic": false},
{"isOnline": true, "isLive": false, "hasPic": true},
{"isOnline": false, "isLive": false, "hasPic": false},
{"isOnline": true, "isLive": true, "hasPic": false},
{"isOnline": true, "isLive": false, "hasPic": true},
{"isOnline": true, "isLive": false, "hasPic": false},
{"isOnline": true, "isLive": false, "hasPic": false},
{"isOnline": true, "isLive": false, "hasPic": false},
{"isOnline": true, "isLive": false, "hasPic": false},
];
List<String> topNav = ["推荐", "同城"];
@override
void initState() {
super.initState();
@ -46,65 +61,336 @@ class _IndexPageState extends State<IndexPage> {
}
void changeNav(int active) {
print("当前项: $active");
}
@override
Widget build(BuildContext context) {
final userInfo = Provider.of<UserInfo>(context);
return Column(
children: [
ElevatedButton(
onPressed: () async {
final r = await GlobalModalController.I.enqueue(
ModalRequest(
type: 'friend_request',
payload: {
'userName': '一夏',
'avatar': 'https://picsum.photos/100',
'userId': 'u1001',
},
dedupeKey: 'friendReq:u1001',
ttl: const Duration(minutes: 2),
timeout: const Duration(seconds: 20),
),
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('好友申请结果: ${r.action}')),
);
},
child: const Text('模拟好友申请弹窗'),
return Container(
padding: EdgeInsets.symmetric(horizontal: 25.w),
constraints: BoxConstraints(minHeight: ScreenUtil().setHeight(1220)),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromRGBO(248, 242, 255, 1.0), // rgba(248, 242, 255, 1)
Color.fromRGBO(247, 247, 247, 1.0), // rgba(247, 247, 247, 1)
],
stops: [0.0, 1.0],
),
const SizedBox(height: 12),
ElevatedButton(
onPressed: () async {
final r = await GlobalModalController.I.enqueue(
ModalRequest(
type: 'live_invite',
payload: {
'roomId': 'room-2025',
'roomName': '技术分享房',
'inviter': '主播小栈',
'countdownSec': 10,
},
dedupeKey: 'liveInvite:room-2025',
priority: ModalPriority.high,
ttl: const Duration(seconds: 30),
timeout: const Duration(seconds: 12),
),
child: Column(
children: [
HomeAppbar(topNav: topNav, changeNav: changeNav,),
...userList.map((e){
return UserItem(item: e);
}),
],
),
);
}
}
class UserItem extends StatefulWidget {
final Map item;
const UserItem({super.key, required this.item});
@override
State<UserItem> createState() => _UserItemState();
}
class _UserItemState extends State<UserItem> {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(vertical: 34.w, horizontal: 22.w),
margin: EdgeInsets.only(bottom: 20.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(18.w)),
color: Colors.white
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
Container(
width: 116.w,
height: 116.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(116.w)),
border: Border.all(width: 1, color: widget.item["isOnline"] && widget.item["isLive"] ? const Color.fromRGBO(192, 86, 233, 1) : Colors.transparent)
),
child: Image.asset(
"assets/user_avatar.png",
width: 116.w,
),
),
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('连麦邀请结果: ${r.action}')),
);
},
child: const Text('模拟直播连麦邀请'),
),
const SizedBox(height: 12),
ElevatedButton(
onPressed: () async {
context.pushNamed(RouteNames.test, queryParameters: {'a': '10', 'b': '20'});
},
child: const Text('测试go router跳转'),
),
],
if(widget.item["isOnline"] && !widget.item["isLive"]) Positioned(
right: 0,
bottom: 0,
child: Container(
width: 22.w,
height: 22.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(22.w)),
color: const Color.fromRGBO(43, 255, 132, 1)
),
),
),
if(widget.item["isOnline"] && widget.item["isLive"]) Positioned(
bottom: 0,
left: 23.w,
child: Container(
width: 70.w,
height: 28.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(28.w)),
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(197, 85, 232, 1.0), // rgba(197, 85, 232, 1)
Color.fromRGBO(142, 99, 250, 1.0), // rgba(142, 99, 250, 1)
],
stops: [0.0, 1.0],
),
),
child: Center(
child: Text(
"直播中",
style: TextStyle(
fontSize: 16.w,
color: Colors.white
),
),
),
),
)
],
),
SizedBox(width: 27.w,),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: 508.w,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Text(
"林园园",
style: TextStyle(
fontSize: 30.w,
color: const Color.fromRGBO(51, 51, 51, 1),
fontWeight: FontWeight.w500
),
),
SizedBox(width: 17.w,),
if(widget.item["isOnline"] && !widget.item["isLive"]) Container(
width: 66.w,
height: 26.w,
margin: EdgeInsets.only(right: 5.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(26.w)),
color: const Color.fromRGBO(234, 255, 219, 1)
),
child: Center(
child: Text(
"在线",
style: TextStyle(
fontSize: 18.w,
color: const Color.fromRGBO(38, 199, 124, 1)
),
),
),
),
Container(
width: 87.w,
height: 26.w,
margin: EdgeInsets.only(right: 11.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(26.w)),
color: const Color.fromRGBO(246, 237, 255, 1)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
"assets/real_name.png",
width: 16.w,
),
SizedBox(width: 5.w,),
Text(
"实名",
style: TextStyle(
fontSize: 18.w,
color: const Color.fromRGBO(160, 92, 255, 1)
),
)
],
),
),
if(widget.item["isOnline"] && widget.item["isLive"]) Container(
width: 120.w,
height: 26.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(26.w)),
color: const Color.fromRGBO(234, 255, 219, 1)
),
child: Center(
child: Text(
"视频相亲中",
style: TextStyle(
fontSize: 18.w,
color: const Color.fromRGBO(38, 199, 124, 1)
),
),
),
)
],
),
if(widget.item["isOnline"] && !widget.item["isLive"]) Container(
width: 81.w,
height: 40.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.w)),
gradient: LinearGradient(
begin: Alignment.centerLeft, // 90deg
end: Alignment.centerRight,
colors: [
Color.fromRGBO(61, 138, 224, 1.0), // rgba(61, 138, 224, 1)
Color.fromRGBO(131, 89, 254, 1.0), // rgba(131, 89, 254, 1)
],
stops: [0.0, 1.0],
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
"assets/H.png",
height: 22.w,
),
SizedBox(width: 4.w,),
Image.asset(
"assets/i.png",
height: 22.w,
)
],
),
),
if(!widget.item["isOnline"]) Container(
width: 81.w,
height: 40.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.w)),
gradient: LinearGradient(
begin: Alignment.centerLeft, // 90deg
end: Alignment.centerRight,
colors: [
Color.fromRGBO(61, 138, 224, 1.0), // rgba(61, 138, 224, 1)
Color.fromRGBO(131, 89, 254, 1.0), // rgba(131, 89, 254, 1)
],
stops: [0.0, 1.0],
),
),
child: Center(
child: Text(
"发消息",
style: TextStyle(
fontSize: 20.w,
color: Colors.white
),
),
),
),
if(widget.item["isOnline"] && widget.item["isLive"])Container(
width: 119.w,
height: 40.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.w)),
gradient: LinearGradient(
begin: Alignment.centerLeft, // 90deg
end: Alignment.centerRight,
colors: [
Color.fromRGBO(61, 138, 224, 1.0), // rgba(61, 138, 224, 1)
Color.fromRGBO(131, 89, 254, 1.0), // rgba(131, 89, 254, 1)
],
stops: [0.0, 1.0],
),
),
child: Center(
child: Text(
"进入直播间",
style: TextStyle(
fontSize: 20.w,
color: Colors.white
),
),
),
),
],
),
),
SizedBox(height: 5.w,),
Text(
"23岁 · 白云区",
style: TextStyle(
color: const Color.fromRGBO(51, 51, 51, 1),
fontSize: 25.w
),
),
SizedBox(height: 5.w,),
SizedBox(
width: 508.w,
child: Text(
"我想找一个有缘的异性,快来联系我吧快来我想找一个有缘的异性,快来联系我吧快来..........",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: const Color.fromRGBO(51, 51, 51, .6),
fontSize: 25.w
),
),
),
SizedBox(height: 5.w,),
if(widget.item["hasPic"]) SizedBox(
width: 508.w,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.asset(
"assets/pic1.png",
width: 165.w,
height: 165.w,
),
Image.asset(
"assets/pic2.png",
width: 165.w,
height: 165.w,
),
Image.asset(
"assets/pic3.png",
width: 165.w,
height: 165.w,
),
],
),
)
],
)
],
),
);
}
}

268
lib/pages/live_page.dart

@ -1,6 +1,8 @@
import 'package:dating_touchme_app/components/home_appbar.dart';
import 'package:dating_touchme_app/provide/user_info.dart';
import 'package:dating_touchme_app/utils/storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
class LivePage extends StatefulWidget {
@ -12,26 +14,274 @@ class LivePage extends StatefulWidget {
class _LivePageState extends State<LivePage> {
int nowNum = 0;
String nowToken = "";
List<String> topNav = ["相亲", "聚会脱单"];
List<Map> liveList = [
{"isNew": true},
{"isNew": true},
{"isNew": false},
{"isNew": false},
{"isNew": false},
{"isNew": false},
{"isNew": false},
{"isNew": false},
{"isNew": false},
{"isNew": false},
];
List<String> tabList = [
"全部", "同城", "相亲视频", "相亲语音"
];
int active = 0;
@override
void initState() {
getData();
super.initState();
}
getData() async {
nowNum = Provider.of<UserInfo>(context, listen: false).current;
nowToken = await Storage().getStorage("token");
setState(() {
});
void changeNav(int active) {
print("当前项: $active");
}
@override
Widget build(BuildContext context) {
return Text("直播页面");
return Container(
padding: EdgeInsets.symmetric(horizontal: 24.w),
constraints: BoxConstraints(minHeight: ScreenUtil().setHeight(1220)),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter, // 180deg
end: Alignment.bottomCenter,
colors: [
Color.fromRGBO(248, 242, 255, 1.0), // rgba(248, 242, 255, 1)
Color.fromRGBO(247, 247, 247, 1.0), // rgba(247, 247, 247, 1)
],
stops: [0.0, 1.0], // 0% 100%
),
),
child: Column(
children: [
HomeAppbar(topNav: topNav, changeNav: changeNav,),
Container(
width: 702.w,
height: 91.w,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
...tabList.asMap().entries.map((entry){
return Container(
margin: EdgeInsets.only(right: 55.w),
child: InkWell(
onTap: (){
active = entry.key;
setState(() {
});
},
child: Container(
height: 43.w,
padding: EdgeInsets.symmetric(horizontal: active == entry.key ? 30.w : 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(43.w)),
color: Color.fromRGBO(108, 105, 244, active == entry.key ? 1 : 0)
),
child: Center(
child: Text(
entry.value,
style: TextStyle(
fontSize: 24.w,
color: active == entry.key ? Colors.white :const Color.fromRGBO(51, 51, 51, .7),
fontWeight: active == entry.key ? FontWeight.w700 : FontWeight.w500
),
),
),
),
),
);
}),
],
),
),
),
Wrap(
spacing: 15.w,
runSpacing: 15.w,
children: [
...liveList.map((e){
return LiveItem(item: e,);
}),
],
)
],
),
);
}
}
class LiveItem extends StatefulWidget {
final Map item;
const LiveItem({super.key, required this.item});
@override
State<LiveItem> createState() => _LiveItemState();
}
class _LiveItemState extends State<LiveItem> {
@override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(20.w)),
child: Stack(
children: [
Container(
width: 343.w,
height: 343.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.w))
),
child: Image.network(
"https://picsum.photos/400",
width: 343.w,
height: 343.w,
),
),
Positioned(
top: 0,
left: 0,
child: Stack(
children: [
Image.asset(
"assets/subscript.png",
width: 113.w,
height: 32.w,
),
SizedBox(
height: 32.w,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(width: 10.w,),
Image.asset(
"assets/location_icon.png",
width: 12.w,
height: 14.w,
),
SizedBox(width: 6.w,),
Text(
"49.9km",
style: TextStyle(
fontSize: 16.w,
color: Colors.white,
fontWeight: FontWeight.w500
),
)
],
),
)
],
),
),
if(widget.item["isNew"]) Positioned(
top: 19.w,
right: 17.w,
child: Container(
width: 79.w,
height: 26.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(26.w)),
color: const Color.fromRGBO(0, 0, 0, .3)
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 10.w,
height: 10.w,
margin: EdgeInsets.only(right: 6.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10.w)),
color: const Color.fromRGBO(255, 209, 43, 1)
),
),
Text(
"等待",
style: TextStyle(
fontSize: 16.w,
color: Colors.white,
fontWeight: FontWeight.w500
),
)
],
),
),
),
Positioned(
left: 18.w,
bottom: 13.w,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 128.w,
child: Text(
"一直一直在等你一直一直在等你......",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 16.w,
color: Colors.white,
fontWeight: FontWeight.w500
),
),
),
SizedBox(height: 5.w,),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"福州 | 28岁",
style: TextStyle(
fontSize: 22.w,
color: Colors.white,
fontWeight: FontWeight.w500
),
),
SizedBox(width: 11.w,),
if(widget.item["isNew"]) Container(
width: 65.w,
height: 21.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(21.w)),
color: const Color.fromRGBO(255, 206, 28, .8)
),
child: Center(
child: Text(
"新人",
style: TextStyle(
fontSize: 16.w,
color: Colors.white,
fontWeight: FontWeight.w500
),
),
),
)
],
)
],
),
)
],
),
);
}
}

2
pubspec.yaml

@ -71,6 +71,8 @@ flutter:
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
assets:
- assets/
# To add assets to your application, add an assets section, like this:
# assets:

30
test/widget_test.dart

@ -1,30 +0,0 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:dating_touchme_app/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}
Loading…
Cancel
Save