接入圈子列表数据,增加视频播放页
This commit is contained in:
parent
e065158817
commit
f3cf90898e
Binary file not shown.
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.5 KiB |
@ -38,12 +38,6 @@ class Call_outLogic extends GetxController {
|
|||||||
videoPlayerController?.dispose();
|
videoPlayerController?.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
videoPlayerController?.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() async {
|
void onInit() async {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
|
|||||||
@ -5,3 +5,170 @@ class CircleState {
|
|||||||
///Initialize variables
|
///Initialize variables
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Lists {
|
||||||
|
List<Album>? album;
|
||||||
|
Chat? chat;
|
||||||
|
String? content;
|
||||||
|
int? id;
|
||||||
|
bool? isQueen;
|
||||||
|
User? user;
|
||||||
|
|
||||||
|
Lists(
|
||||||
|
{this.album, this.chat, this.content, this.id, this.isQueen, this.user});
|
||||||
|
|
||||||
|
Lists.fromJson(Map<String, dynamic> json) {
|
||||||
|
if (json['album'] != null) {
|
||||||
|
album = <Album>[];
|
||||||
|
json['album'].forEach((v) {
|
||||||
|
album!.add(new Album.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
chat = json['chat'] != null ? new Chat.fromJson(json['chat']) : null;
|
||||||
|
content = json['content'];
|
||||||
|
id = json['id'];
|
||||||
|
isQueen = json['is_queen'];
|
||||||
|
user = json['user'] != null ? new User.fromJson(json['user']) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
if (this.album != null) {
|
||||||
|
data['album'] = this.album!.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
if (this.chat != null) {
|
||||||
|
data['chat'] = this.chat!.toJson();
|
||||||
|
}
|
||||||
|
data['content'] = this.content;
|
||||||
|
data['id'] = this.id;
|
||||||
|
data['is_queen'] = this.isQueen;
|
||||||
|
if (this.user != null) {
|
||||||
|
data['user'] = this.user!.toJson();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Album {
|
||||||
|
int? type;
|
||||||
|
String? url;
|
||||||
|
|
||||||
|
Album({this.type, this.url});
|
||||||
|
|
||||||
|
Album.fromJson(Map<String, dynamic> json) {
|
||||||
|
type = json['type'];
|
||||||
|
url = json['url'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['type'] = this.type;
|
||||||
|
data['url'] = this.url;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Chat {
|
||||||
|
String? accountId;
|
||||||
|
int? count;
|
||||||
|
List<Users>? users;
|
||||||
|
|
||||||
|
Chat({this.accountId, this.count, this.users});
|
||||||
|
|
||||||
|
Chat.fromJson(Map<String, dynamic> json) {
|
||||||
|
accountId = json['account_id'];
|
||||||
|
count = json['count'];
|
||||||
|
if (json['users'] != null) {
|
||||||
|
users = <Users>[];
|
||||||
|
json['users'].forEach((v) {
|
||||||
|
users!.add(new Users.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['account_id'] = this.accountId;
|
||||||
|
data['count'] = this.count;
|
||||||
|
if (this.users != null) {
|
||||||
|
data['users'] = this.users!.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Users {
|
||||||
|
String? avatar;
|
||||||
|
int? id;
|
||||||
|
String? nickname;
|
||||||
|
|
||||||
|
Users({this.avatar, this.id, this.nickname});
|
||||||
|
|
||||||
|
Users.fromJson(Map<String, dynamic> json) {
|
||||||
|
avatar = json['avatar'];
|
||||||
|
id = json['id'];
|
||||||
|
nickname = json['nickname'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['avatar'] = this.avatar;
|
||||||
|
data['id'] = this.id;
|
||||||
|
data['nickname'] = this.nickname;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class User {
|
||||||
|
String? avatar;
|
||||||
|
String? city;
|
||||||
|
int? gender;
|
||||||
|
int? id;
|
||||||
|
double? lat;
|
||||||
|
double? lng;
|
||||||
|
String? nickname;
|
||||||
|
int? orientation;
|
||||||
|
int? role;
|
||||||
|
int? vip;
|
||||||
|
|
||||||
|
User(
|
||||||
|
{this.avatar,
|
||||||
|
this.city,
|
||||||
|
this.gender,
|
||||||
|
this.id,
|
||||||
|
this.lat,
|
||||||
|
this.lng,
|
||||||
|
this.nickname,
|
||||||
|
this.orientation,
|
||||||
|
this.role,
|
||||||
|
this.vip});
|
||||||
|
|
||||||
|
User.fromJson(Map<String, dynamic> json) {
|
||||||
|
avatar = json['avatar'];
|
||||||
|
city = json['city'];
|
||||||
|
gender = json['gender'];
|
||||||
|
id = json['id'];
|
||||||
|
lat = json['lat'] ?? 0.0;
|
||||||
|
lng = json['lng'] ?? 0.0;
|
||||||
|
nickname = json['nickname'];
|
||||||
|
orientation = json['orientation'];
|
||||||
|
role = json['role'];
|
||||||
|
vip = json['vip'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['avatar'] = this.avatar;
|
||||||
|
data['city'] = this.city;
|
||||||
|
data['gender'] = this.gender;
|
||||||
|
data['id'] = this.id;
|
||||||
|
data['lat'] = this.lat;
|
||||||
|
data['lng'] = this.lng;
|
||||||
|
data['nickname'] = this.nickname;
|
||||||
|
data['orientation'] = this.orientation;
|
||||||
|
data['role'] = this.role;
|
||||||
|
data['vip'] = this.vip;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,19 +1,45 @@
|
|||||||
|
import 'dart:ffi';
|
||||||
|
|
||||||
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:circle_app/app/circle/logic.dart';
|
import 'package:circle_app/app/circle/logic.dart';
|
||||||
|
import 'package:circle_app/app/circle/state.dart';
|
||||||
|
import 'package:circle_app/app/circle/widgets/list_logic.dart';
|
||||||
|
import 'package:circle_app/app/circle/widgets/video_item.dart';
|
||||||
|
import 'package:circle_app/router/app_routers.dart';
|
||||||
import 'package:circle_app/util/util.dart';
|
import 'package:circle_app/util/util.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:get/get_core/src/get_main.dart';
|
import 'package:get/get_core/src/get_main.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
class InfoListView extends StatelessWidget {
|
class InfoListView extends StatelessWidget {
|
||||||
|
// Get.lazyPut(() => ListLogic());
|
||||||
|
|
||||||
CircleLogic logic;
|
CircleLogic logic;
|
||||||
Circle bean;
|
Circle bean;
|
||||||
int index;
|
int index;
|
||||||
final ScrollController scrollController = ScrollController();
|
|
||||||
|
|
||||||
InfoListView(this.index,this.bean,this.logic, {super.key});
|
InfoListView(this.index, this.bean, this.logic, {super.key});
|
||||||
|
|
||||||
|
List<String> genderList = ['男', '女,' 'MTF', 'FTM', 'CD', '酷儿'];
|
||||||
|
List<String> orientationList = [
|
||||||
|
'异性恋',
|
||||||
|
'同性恋',
|
||||||
|
'双性恋',
|
||||||
|
'泛性恋',
|
||||||
|
'无性恋',
|
||||||
|
'智性恋',
|
||||||
|
'性单恋'
|
||||||
|
];
|
||||||
|
List<String> roleList = ['Sado', 'Maso', 'Dom', 'Sub', 'Switch'];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
Get.lazyPut(() => ListLogic());
|
||||||
|
final listsLg = Get.find<ListLogic>();
|
||||||
|
listsLg.loadCallOutListData(bean.id.toString());
|
||||||
|
|
||||||
TextSpan descSpan;
|
TextSpan descSpan;
|
||||||
TextSpan span;
|
TextSpan span;
|
||||||
if (bean.intro.length > 60) {
|
if (bean.intro.length > 60) {
|
||||||
@ -37,7 +63,6 @@ class InfoListView extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
List<JoinUser> urlList = bean.lastJoinUsers;
|
List<JoinUser> urlList = bean.lastJoinUsers;
|
||||||
List<Widget> widgets = [];
|
List<Widget> widgets = [];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -49,11 +74,15 @@ class InfoListView extends StatelessWidget {
|
|||||||
i++;
|
i++;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return GetBuilder<ListLogic>(
|
||||||
|
assignId: true,
|
||||||
|
builder: (listLogic) {
|
||||||
return ClipRRect(
|
return ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(10.sp),
|
borderRadius: BorderRadius.circular(10.sp),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: Get.width,
|
width: Get.width,
|
||||||
margin: EdgeInsets.only(left: index > 0 ? 4.sp : 0, right: 4.sp),
|
margin:
|
||||||
|
EdgeInsets.only(left: index > 0 ? 4.sp : 0, right: 4.sp),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
@ -69,19 +98,27 @@ class InfoListView extends StatelessWidget {
|
|||||||
height: Get.height,
|
height: Get.height,
|
||||||
width: Get.width,
|
width: Get.width,
|
||||||
margin: EdgeInsets.only(top: 72.sp),
|
margin: EdgeInsets.only(top: 72.sp),
|
||||||
child: ListView.builder(
|
child: RefreshIndicator(
|
||||||
controller: scrollController,
|
onRefresh: () async {
|
||||||
itemCount: 10,
|
listLogic.refreshData();
|
||||||
|
},
|
||||||
|
child: listLogic.lists.isEmpty
|
||||||
|
? loaddingWidget(true)
|
||||||
|
: ListView.builder(
|
||||||
|
scrollDirection: Axis.vertical,
|
||||||
|
controller: listLogic.scrollController,
|
||||||
|
itemCount: listLogic.lists.length + 2,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.only(left: 12.sp, right: 12.sp),
|
padding: EdgeInsets.only(
|
||||||
|
left: 12.sp, right: 12.sp),
|
||||||
height: 88.sp,
|
height: 88.sp,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
image: AssetImage(
|
image: AssetImage(getCircleImage(
|
||||||
getCircleImage('circle_desc')))),
|
'circle_desc')))),
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.only(top: 14.sp),
|
margin: EdgeInsets.only(top: 14.sp),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -97,7 +134,8 @@ class InfoListView extends StatelessWidget {
|
|||||||
child: RichText(
|
child: RichText(
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
text: TextSpan(children: <InlineSpan>[
|
text: TextSpan(
|
||||||
|
children: <InlineSpan>[
|
||||||
descSpan,
|
descSpan,
|
||||||
span
|
span
|
||||||
])),
|
])),
|
||||||
@ -112,7 +150,8 @@ class InfoListView extends StatelessWidget {
|
|||||||
height: 30.sp,
|
height: 30.sp,
|
||||||
width: 30.0.sp +
|
width: 30.0.sp +
|
||||||
15.sp *
|
15.sp *
|
||||||
(widgets.length - 1.sp),
|
(widgets.length -
|
||||||
|
1.sp),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: widgets,
|
children: widgets,
|
||||||
),
|
),
|
||||||
@ -142,13 +181,21 @@ class InfoListView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else if (index == 1) {
|
} else if (listLogic.lists.length + 1 >
|
||||||
return vipDynamicItem(bean);
|
index) {
|
||||||
|
Lists lists = listLogic.lists[index - 1];
|
||||||
|
if (lists.isQueen!) {
|
||||||
|
return vipDynamicItem(lists);
|
||||||
} else {
|
} else {
|
||||||
return normalDynamicItem(bean);
|
return normalDynamicItem(lists);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return loaddingWidget(
|
||||||
|
listLogic.callOutMore);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: Radius.circular(10.sp),
|
topLeft: Radius.circular(10.sp),
|
||||||
@ -159,8 +206,8 @@ class InfoListView extends StatelessWidget {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
image:
|
image: AssetImage(
|
||||||
AssetImage(getCircleImage('top_circle_bg')))),
|
getCircleImage('top_circle_bg')))),
|
||||||
child: Row(
|
child: Row(
|
||||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
@ -169,7 +216,7 @@ class InfoListView extends StatelessWidget {
|
|||||||
height: 42.sp,
|
height: 42.sp,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
gradient: LinearGradient(
|
gradient: const LinearGradient(
|
||||||
begin: Alignment.topCenter,
|
begin: Alignment.topCenter,
|
||||||
end: Alignment.bottomCenter,
|
end: Alignment.bottomCenter,
|
||||||
colors: [
|
colors: [
|
||||||
@ -191,7 +238,8 @@ class InfoListView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.only(left: 8.sp, top: 12.sp),
|
padding:
|
||||||
|
EdgeInsets.only(left: 8.sp, top: 12.sp),
|
||||||
// alignment: Alignment.,
|
// alignment: Alignment.,
|
||||||
height: 72.sp,
|
height: 72.sp,
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -243,7 +291,10 @@ class InfoListView extends StatelessWidget {
|
|||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
)));
|
)));
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showTextContentDialog(BuildContext context, String msg) {
|
void _showTextContentDialog(BuildContext context, String msg) {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
@ -304,35 +355,39 @@ class InfoListView extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///至尊喊话
|
///至尊喊话
|
||||||
vipDynamicItem(Circle bean) {
|
vipDynamicItem(Lists bean) {
|
||||||
Text descText = Text(
|
Text descText = Text(
|
||||||
bean.intro,
|
bean.content!,
|
||||||
style: TextStyle(color: Colors.white, fontSize: 14.sp),
|
style: TextStyle(color: Colors.white, fontSize: 14.sp),
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
List<JoinUser> urlList = bean.lastJoinUsers;
|
// List<JoinUser> urlList = bean.lastJoinUsers;
|
||||||
List<Widget> widgets = [];
|
List<Widget> widgets = [];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
urlList.forEach((element) {
|
bean.chat!.users!.forEach((element) {
|
||||||
widgets.add(Positioned(
|
widgets.add(Positioned(
|
||||||
left: 12.sp * index,
|
left: 12.sp * index,
|
||||||
child: circleWidget(element.avatar, width: 24),
|
child: circleWidget(element.avatar!, width: 24),
|
||||||
));
|
));
|
||||||
index++;
|
index++;
|
||||||
});
|
});
|
||||||
|
if (widgets.isNotEmpty) {
|
||||||
widgets.add(Positioned(
|
widgets.add(Positioned(
|
||||||
left: 12.sp * urlList.length,
|
left: 12.sp * bean.chat!.users!.length,
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
getCircleImage('more'),
|
getCircleImage('more'),
|
||||||
width: 24.sp,
|
width: 24.sp,
|
||||||
)));
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
double widgetHeight = 250.sp + contentHeight(bean.content!);
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.only(top: 10.sp),
|
margin: EdgeInsets.only(top: 10.sp),
|
||||||
width: Get.width,
|
width: Get.width,
|
||||||
height: 279.sp,
|
height: widgetHeight,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
@ -374,7 +429,7 @@ class InfoListView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
ClipOval(
|
ClipOval(
|
||||||
child: Image.network(
|
child: Image.network(
|
||||||
'https://p3-passport.byteimg.com/img/user-avatar/eb429d4dbb3c246f580a6f7894f2b246~100x100.awebp',
|
bean.user!.avatar!,
|
||||||
width: 40.sp,
|
width: 40.sp,
|
||||||
height: 40.sp,
|
height: 40.sp,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
@ -392,7 +447,7 @@ class InfoListView extends StatelessWidget {
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'圈子名称',
|
bean.user!.nickname!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 18.sp,
|
fontSize: 18.sp,
|
||||||
@ -401,7 +456,9 @@ class InfoListView extends StatelessWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: 8.sp,
|
width: 8.sp,
|
||||||
),
|
),
|
||||||
Image.asset(
|
bean.user!.vip! == 0
|
||||||
|
? Container()
|
||||||
|
: Image.asset(
|
||||||
getCircleImage('vip'),
|
getCircleImage('vip'),
|
||||||
width: 36.sp,
|
width: 36.sp,
|
||||||
)
|
)
|
||||||
@ -427,7 +484,7 @@ class InfoListView extends StatelessWidget {
|
|||||||
Color(0xffB5D3FF)
|
Color(0xffB5D3FF)
|
||||||
])),
|
])),
|
||||||
child: Text(
|
child: Text(
|
||||||
'男.33.DOM.异性恋',
|
'${genderList[bean.user!.gender!]}.${'33'}.${roleList[bean.user!.role!]}.${orientationList[bean.user!.orientation!]}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontSize: 12.sp,
|
fontSize: 12.sp,
|
||||||
@ -443,6 +500,7 @@ class InfoListView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
// margin: EdgeInsets.only(top: 4.sp),
|
// margin: EdgeInsets.only(top: 4.sp),
|
||||||
child: descText,
|
child: descText,
|
||||||
),
|
),
|
||||||
@ -490,18 +548,28 @@ class InfoListView extends StatelessWidget {
|
|||||||
colors: [Color(0xff261240), Color(0xff122D40)])),
|
colors: [Color(0xff261240), Color(0xff122D40)])),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
widgets.isNotEmpty
|
||||||
|
? Container(
|
||||||
width: 24 + 12.sp * widgets.length - 12.sp,
|
width: 24 + 12.sp * widgets.length - 12.sp,
|
||||||
height: 24.sp,
|
height: 24.sp,
|
||||||
child: Stack(children: widgets),
|
child: Stack(children: widgets),
|
||||||
),
|
)
|
||||||
|
: Container(),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 4.sp,
|
width: 4.sp,
|
||||||
),
|
),
|
||||||
Expanded(
|
widgets.isNotEmpty
|
||||||
|
? Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'1位圈友已私聊',
|
'${bean.chat!.count!}位圈友已私聊',
|
||||||
style: TextStyle(color: Colors.white, fontSize: 12.sp),
|
style: TextStyle(
|
||||||
|
color: Colors.white, fontSize: 12.sp),
|
||||||
|
))
|
||||||
|
: Expanded(
|
||||||
|
child: Text(
|
||||||
|
'赶紧成为第一位私聊ta的圈友吧',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white, fontSize: 12.sp),
|
||||||
)),
|
)),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
getCircleImage('chat'),
|
getCircleImage('chat'),
|
||||||
@ -519,37 +587,55 @@ class InfoListView extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///普通图文喊话
|
///普通图文喊话
|
||||||
normalDynamicItem(Circle bean) {
|
normalDynamicItem(Lists bean) {
|
||||||
Text descText = Text(
|
Text descText = Text(
|
||||||
bean.intro,
|
bean.content!,
|
||||||
style: TextStyle(color: Colors.white, fontSize: 14.sp),
|
style: TextStyle(color: Colors.white, fontSize: 14.sp),
|
||||||
maxLines: 2,
|
// maxLines: 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
List<String> urlList = [
|
double picHeight = 0.0;
|
||||||
'https://p3-passport.byteimg.com/img/user-avatar/eb429d4dbb3c246f580a6f7894f2b246~100x100.awebp',
|
|
||||||
'https://p3-passport.byteimg.com/img/user-avatar/eb429d4dbb3c246f580a6f7894f2b246~100x100.awebp',
|
int type = 0;
|
||||||
'https://p3-passport.byteimg.com/img/user-avatar/eb429d4dbb3c246f580a6f7894f2b246~100x100.awebp'
|
if (bean.album != null) {
|
||||||
];
|
if (bean.album!.isNotEmpty) {
|
||||||
|
Album info = bean.album!.first!;
|
||||||
|
type = info.type!;
|
||||||
|
|
||||||
|
if (info.type == 1) {
|
||||||
|
if (bean.album!.length > 3) {
|
||||||
|
picHeight = 218.sp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
picHeight = 109.sp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<Widget> widgets = [];
|
List<Widget> widgets = [];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
urlList.forEach((element) {
|
bean!.chat!.users!.forEach((element) {
|
||||||
widgets.add(Positioned(
|
widgets.add(Positioned(
|
||||||
left: 12.sp * index,
|
left: 12.sp * index,
|
||||||
child: circleWidget(element, width: 24),
|
child: GestureDetector(
|
||||||
|
onTap: () {},
|
||||||
|
child: circleWidget(element.avatar!, width: 24),
|
||||||
|
),
|
||||||
));
|
));
|
||||||
index++;
|
index++;
|
||||||
});
|
});
|
||||||
|
if (widgets.isNotEmpty) {
|
||||||
widgets.add(Positioned(
|
widgets.add(Positioned(
|
||||||
left: 12.sp * urlList.length,
|
left: 12.sp * bean.chat!.users!.length,
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
getCircleImage('more'),
|
getCircleImage('more'),
|
||||||
width: 24.sp,
|
width: 24.sp,
|
||||||
)));
|
)));
|
||||||
|
}
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.only(top: 10.sp),
|
margin: EdgeInsets.only(top: 10.sp),
|
||||||
width: Get.width,
|
width: Get.width,
|
||||||
height: 279.sp,
|
height: 130.sp + contentHeight(bean.content!) + picHeight,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
@ -561,11 +647,23 @@ class InfoListView extends StatelessWidget {
|
|||||||
Positioned(
|
Positioned(
|
||||||
right: 2.sp,
|
right: 2.sp,
|
||||||
top: 2.sp,
|
top: 2.sp,
|
||||||
child: Image.asset(getCircleImage('location')),
|
child: Stack(
|
||||||
height: 18.sp,
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
getCircleImage('location'),
|
||||||
|
height: 20.sp,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
bean.user!.city ?? '外星',
|
||||||
|
style: TextStyle(color: Colors.white, fontSize: 12.sp),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
// height: 18.sp,
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
height: 279.sp,
|
height: 130.sp + contentHeight(bean.content!) + picHeight,
|
||||||
width: Get.width,
|
width: Get.width,
|
||||||
padding: EdgeInsets.only(left: 12.sp, right: 12.sp),
|
padding: EdgeInsets.only(left: 12.sp, right: 12.sp),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -585,7 +683,7 @@ class InfoListView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
ClipOval(
|
ClipOval(
|
||||||
child: Image.network(
|
child: Image.network(
|
||||||
'https://p3-passport.byteimg.com/img/user-avatar/eb429d4dbb3c246f580a6f7894f2b246~100x100.awebp',
|
bean.user!.avatar!,
|
||||||
width: 40.sp,
|
width: 40.sp,
|
||||||
height: 40.sp,
|
height: 40.sp,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
@ -603,7 +701,7 @@ class InfoListView extends StatelessWidget {
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'圈子名称',
|
bean.user!.nickname! ?? '',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 18.sp,
|
fontSize: 18.sp,
|
||||||
@ -612,7 +710,9 @@ class InfoListView extends StatelessWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: 8.sp,
|
width: 8.sp,
|
||||||
),
|
),
|
||||||
Image.asset(
|
bean.user!.vip! == 0
|
||||||
|
? Container()
|
||||||
|
: Image.asset(
|
||||||
getCircleImage('vip'),
|
getCircleImage('vip'),
|
||||||
width: 36.sp,
|
width: 36.sp,
|
||||||
)
|
)
|
||||||
@ -630,7 +730,7 @@ class InfoListView extends StatelessWidget {
|
|||||||
EdgeInsets.only(left: 6.sp, right: 6.sp),
|
EdgeInsets.only(left: 6.sp, right: 6.sp),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(9.sp),
|
borderRadius: BorderRadius.circular(9.sp),
|
||||||
gradient: LinearGradient(
|
gradient: const LinearGradient(
|
||||||
begin: Alignment(0.25, 0.5),
|
begin: Alignment(0.25, 0.5),
|
||||||
end: Alignment(0.75, 0.5),
|
end: Alignment(0.75, 0.5),
|
||||||
colors: [
|
colors: [
|
||||||
@ -638,7 +738,7 @@ class InfoListView extends StatelessWidget {
|
|||||||
Color(0xffB5D3FF)
|
Color(0xffB5D3FF)
|
||||||
])),
|
])),
|
||||||
child: Text(
|
child: Text(
|
||||||
'男.33.DOM.异性恋',
|
'${genderList[bean.user!.gender!]}.${'33'}.${roleList[bean.user!.role!]}.${orientationList[bean.user!.orientation!]}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontSize: 12.sp,
|
fontSize: 12.sp,
|
||||||
@ -654,41 +754,58 @@ class InfoListView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
// margin: EdgeInsets.only(top: 4.sp),
|
// margin: EdgeInsets.only(top: 4.sp),
|
||||||
child: descText,
|
child: descText,
|
||||||
),
|
),
|
||||||
Container(
|
picHeight > 0
|
||||||
height: 100.sp,
|
? Container(
|
||||||
|
height: picHeight,
|
||||||
margin: EdgeInsets.only(top: 5.sp),
|
margin: EdgeInsets.only(top: 5.sp),
|
||||||
child: GridView(
|
child: GridView.builder(
|
||||||
|
itemCount: bean.album!.length,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate:
|
||||||
|
SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisCount: 3, //横轴三个子widget
|
crossAxisCount: 3, //横轴三个子widget
|
||||||
crossAxisSpacing: 8.sp,
|
crossAxisSpacing: 8.sp,
|
||||||
|
mainAxisSpacing: 8.sp,
|
||||||
childAspectRatio: 1.0 //宽高比为1时,子widget
|
childAspectRatio: 1.0 //宽高比为1时,子widget
|
||||||
),
|
),
|
||||||
children: <Widget>[
|
itemBuilder: (contentxt, currentIndex) {
|
||||||
ClipRRect(
|
Album album = bean.album![currentIndex];
|
||||||
|
if (album.type == 2) {
|
||||||
|
return ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(6.sp),
|
borderRadius: BorderRadius.circular(6.sp),
|
||||||
child: Image.network(
|
child: VideoItemWidget(album.url!));
|
||||||
'https://pic1.zhimg.com/v2-3be05963f5f3753a8cb75b6692154d4a_720w.jpg?source=172ae18b',
|
}
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
var imgList = <String>[];
|
||||||
|
for (var element in bean.album!) {
|
||||||
|
imgList.add(element.url!);
|
||||||
|
}
|
||||||
|
Get.toNamed(AppRoutes.Swiper, arguments: {
|
||||||
|
'imaglist': imgList,
|
||||||
|
'index': currentIndex
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(6.sp),
|
||||||
|
child: CachedNetworkImage(
|
||||||
|
imageUrl: album.url!,
|
||||||
|
placeholder: (context, url) =>
|
||||||
|
CircularProgressIndicator(
|
||||||
|
color: Color(0xFF07FAFB),
|
||||||
|
),
|
||||||
|
errorWidget: (context, url, error) =>
|
||||||
|
Icon(Icons.error),
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ClipRRect(
|
);
|
||||||
borderRadius: BorderRadius.circular(6.sp),
|
}))
|
||||||
child: Image.network(
|
: Container(),
|
||||||
'https://pic1.zhimg.com/v2-3be05963f5f3753a8cb75b6692154d4a_720w.jpg?source=172ae18b',
|
|
||||||
fit: BoxFit.fill),
|
|
||||||
),
|
|
||||||
ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(6.sp),
|
|
||||||
child: Image.network(
|
|
||||||
'https://pic1.zhimg.com/v2-3be05963f5f3753a8cb75b6692154d4a_720w.jpg?source=172ae18b',
|
|
||||||
fit: BoxFit.fill),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
Container(
|
Container(
|
||||||
height: 34.sp,
|
height: 34.sp,
|
||||||
padding: EdgeInsets.only(left: 5.sp, right: 10.sp),
|
padding: EdgeInsets.only(left: 5.sp, right: 10.sp),
|
||||||
@ -701,18 +818,28 @@ class InfoListView extends StatelessWidget {
|
|||||||
colors: [Color(0xff261240), Color(0xff122D40)])),
|
colors: [Color(0xff261240), Color(0xff122D40)])),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
widgets.isNotEmpty
|
||||||
|
? Container(
|
||||||
width: 24 + 12.sp * widgets.length - 12.sp,
|
width: 24 + 12.sp * widgets.length - 12.sp,
|
||||||
height: 24.sp,
|
height: 24.sp,
|
||||||
child: Stack(children: widgets),
|
child: Stack(children: widgets),
|
||||||
),
|
)
|
||||||
|
: Container(),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 4.sp,
|
width: 4.sp,
|
||||||
),
|
),
|
||||||
Expanded(
|
widgets.isNotEmpty
|
||||||
|
? Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'1位圈友已私聊',
|
'${bean.chat!.count!}位圈友已私聊',
|
||||||
style: TextStyle(color: Colors.white, fontSize: 12.sp),
|
style: TextStyle(
|
||||||
|
color: Colors.white, fontSize: 12.sp),
|
||||||
|
))
|
||||||
|
: Expanded(
|
||||||
|
child: Text(
|
||||||
|
'赶紧成为第一位私聊ta的圈友吧',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white, fontSize: 12.sp),
|
||||||
)),
|
)),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
getCircleImage('chat'),
|
getCircleImage('chat'),
|
||||||
@ -729,7 +856,6 @@ class InfoListView extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
circleWidget(String url, {double width = 30}) {
|
circleWidget(String url, {double width = 30}) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
child: Stack(
|
child: Stack(
|
||||||
@ -751,7 +877,6 @@ class InfoListView extends StatelessWidget {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _showOutCircleDialog(
|
void _showOutCircleDialog(
|
||||||
BuildContext context, CircleLogic controller, Circle bean) {
|
BuildContext context, CircleLogic controller, Circle bean) {
|
||||||
showDialog(
|
showDialog(
|
||||||
@ -889,4 +1014,9 @@ class InfoListView extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double contentHeight(String content) {
|
||||||
|
return calculateTextHeight(
|
||||||
|
content, 14.sp, FontWeight.w300, Get.width - 64.sp, 100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
64
circle_app/lib/app/circle/widgets/list_logic.dart
Normal file
64
circle_app/lib/app/circle/widgets/list_logic.dart
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import 'package:circle_app/app/circle/state.dart';
|
||||||
|
import 'package:circle_app/network/dio_manager.dart';
|
||||||
|
import 'package:circle_app/util/util.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class ListLogic extends GetxController {
|
||||||
|
int callOutPage = 1;
|
||||||
|
|
||||||
|
bool isLoad = true;
|
||||||
|
bool callOutMore = true;
|
||||||
|
var _circleId = '';
|
||||||
|
List<Lists> lists = [];
|
||||||
|
final ScrollController scrollController = ScrollController();
|
||||||
|
|
||||||
|
loadCallOutListData(String circleId) async {
|
||||||
|
_circleId = circleId;
|
||||||
|
var data = await DioManager.instance.get(
|
||||||
|
url: "/up-service/interest/$circleId/callouts",
|
||||||
|
params: {"page": callOutPage, "page_size": "20"});
|
||||||
|
if (data["code"] == 200) {
|
||||||
|
List dataList = data["data"]["lists"];
|
||||||
|
if (callOutPage == 1) {
|
||||||
|
if (lists.isNotEmpty) {
|
||||||
|
lists.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dataList.isNotEmpty) {
|
||||||
|
callOutMore = true;
|
||||||
|
for (var element in dataList) {
|
||||||
|
lists.add(Lists.fromJson(element));
|
||||||
|
}
|
||||||
|
callOutPage++;
|
||||||
|
} else {
|
||||||
|
callOutMore = false;
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
} else {
|
||||||
|
showToast(data["msg"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void refreshData() {
|
||||||
|
callOutPage = 1;
|
||||||
|
callOutMore = true;
|
||||||
|
loadCallOutListData(_circleId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadMore() {
|
||||||
|
loadCallOutListData(_circleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
// TODO: implement onInit
|
||||||
|
super.onInit();
|
||||||
|
scrollController.addListener(() {
|
||||||
|
if (scrollController.position.pixels == scrollController.position.maxScrollExtent) {
|
||||||
|
loadMore();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
112
circle_app/lib/app/circle/widgets/play_video_view.dart
Normal file
112
circle_app/lib/app/circle/widgets/play_video_view.dart
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import 'package:circle_app/util/util.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:video_player/video_player.dart';
|
||||||
|
|
||||||
|
class PlayVideoView extends StatefulWidget {
|
||||||
|
String url;
|
||||||
|
PlayVideoView(this.url, {Key? key}) : super(key: key);
|
||||||
|
@override
|
||||||
|
State<PlayVideoView> createState() => _PlayVideoViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PlayVideoViewState extends State<PlayVideoView> {
|
||||||
|
VideoPlayerController? videoPlayerController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
videoPlayerController = VideoPlayerController.network(widget.url)
|
||||||
|
..initialize().then((_) {
|
||||||
|
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
|
||||||
|
setState(() {});
|
||||||
|
});
|
||||||
|
|
||||||
|
videoPlayerController?.addListener(() async {
|
||||||
|
// value.position == value.duration
|
||||||
|
if (videoPlayerController?.value.position ==
|
||||||
|
videoPlayerController?.value.duration) {
|
||||||
|
// videoPlayerController?.pause();
|
||||||
|
await videoPlayerController?.seekTo(Duration.zero);
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
// TODO: implement dispose
|
||||||
|
super.dispose();
|
||||||
|
videoPlayerController?.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Colors.black,
|
||||||
|
body: Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: Get.width,
|
||||||
|
height: Get.height,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
if (videoPlayerController!.value.isPlaying) {
|
||||||
|
videoPlayerController!.pause();
|
||||||
|
} else {
|
||||||
|
videoPlayerController!.play();
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
AspectRatio(
|
||||||
|
aspectRatio: videoPlayerController!.value.aspectRatio,
|
||||||
|
child: VideoPlayer(videoPlayerController!)),
|
||||||
|
Center(
|
||||||
|
child: videoPlayerController!.value.isPlaying
|
||||||
|
? Container()
|
||||||
|
: Image(
|
||||||
|
image: AssetImage(getMineImage("icon_play")),
|
||||||
|
width: 60.sp,
|
||||||
|
height: 60.sp,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: 0,
|
||||||
|
child: SafeArea(
|
||||||
|
child: SizedBox(
|
||||||
|
width: Get.width,
|
||||||
|
height: 10.sp,
|
||||||
|
child: VideoProgressIndicator(videoPlayerController!,
|
||||||
|
allowScrubbing: true,
|
||||||
|
colors: const VideoProgressColors(
|
||||||
|
playedColor: Colors.white,
|
||||||
|
bufferedColor: Colors.white54,
|
||||||
|
backgroundColor: Colors.black)),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
Positioned(
|
||||||
|
left: 15.sp,
|
||||||
|
top: Get.statusBarHeight,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Get.back();
|
||||||
|
},
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/navigator/back.png',
|
||||||
|
width: 36.sp,
|
||||||
|
height: 36.sp,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
62
circle_app/lib/app/circle/widgets/video_item.dart
Normal file
62
circle_app/lib/app/circle/widgets/video_item.dart
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
import 'package:circle_app/app/circle/widgets/play_video_view.dart';
|
||||||
|
import 'package:circle_app/util/util.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:video_player/video_player.dart';
|
||||||
|
|
||||||
|
class VideoItemWidget extends StatefulWidget {
|
||||||
|
String url;
|
||||||
|
VideoItemWidget(this.url,{Key? key}) : super(key: key);
|
||||||
|
@override
|
||||||
|
State<VideoItemWidget> createState() => _VideoItemWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _VideoItemWidgetState extends State<VideoItemWidget> {
|
||||||
|
VideoPlayerController? videoPlayerController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
videoPlayerController = VideoPlayerController.network(
|
||||||
|
widget.url)
|
||||||
|
..initialize().then((_) {
|
||||||
|
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
|
||||||
|
setState(() {});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
// TODO: implement dispose
|
||||||
|
super.dispose();
|
||||||
|
videoPlayerController?.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Get.to(PlayVideoView(widget.url));
|
||||||
|
},
|
||||||
|
child: AspectRatio(
|
||||||
|
aspectRatio: videoPlayerController!.value.aspectRatio,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
VideoPlayer(videoPlayerController!),
|
||||||
|
Center(
|
||||||
|
child: videoPlayerController!.value.isPlaying
|
||||||
|
? Container()
|
||||||
|
: Image(
|
||||||
|
image: AssetImage(getMineImage("icon_play")),
|
||||||
|
width: 30.sp,
|
||||||
|
height: 30.sp,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,11 +2,11 @@ import 'dart:ui';
|
|||||||
|
|
||||||
import 'package:circle_app/common/values/values.dart';
|
import 'package:circle_app/common/values/values.dart';
|
||||||
import 'package:circle_app/router/app_routers.dart';
|
import 'package:circle_app/router/app_routers.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:get/get_state_manager/get_state_manager.dart';
|
|
||||||
|
|
||||||
class Util {
|
class Util {
|
||||||
|
|
||||||
@ -59,6 +59,16 @@ showToast(String msg) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loaddingWidget(bool isMore) {
|
||||||
|
return Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: isMore ? const CircularProgressIndicator(color: Color(0xFF07FAFB),) : Container(
|
||||||
|
margin:EdgeInsets.only(top: 4.sp,bottom: 4.sp),
|
||||||
|
child: Text('--到底了--',style: TextStyle(color: Colors.white,fontSize: 13.sp),
|
||||||
|
),),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
///value: 文本内容;fontSize : 文字的大小;fontWeight:文字权重;maxWidth:文本框的最大宽度;maxLines:文本支持最大多少行
|
///value: 文本内容;fontSize : 文字的大小;fontWeight:文字权重;maxWidth:文本框的最大宽度;maxLines:文本支持最大多少行
|
||||||
double calculateTextHeight(String value, fontSize, FontWeight fontWeight,
|
double calculateTextHeight(String value, fontSize, FontWeight fontWeight,
|
||||||
double maxWidth, int maxLines) {
|
double maxWidth, int maxLines) {
|
||||||
|
|||||||
@ -76,6 +76,8 @@ dependencies:
|
|||||||
package_info_plus: ^1.4.3+1
|
package_info_plus: ^1.4.3+1
|
||||||
#视频播放器
|
#视频播放器
|
||||||
video_player: ^2.6.1
|
video_player: ^2.6.1
|
||||||
|
#图片缓存
|
||||||
|
cached_network_image: ^3.2.3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user