fmk
3 years ago
20 changed files with 1619 additions and 430 deletions
@ -0,0 +1,376 @@
|
||||
import 'package:dio/dio.dart'; |
||||
import 'package:flutter/material.dart'; |
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; |
||||
import 'package:huixiang/community/community_view/community_comment.dart'; |
||||
import 'package:huixiang/community/community_view/community_dynamic.dart'; |
||||
import 'package:huixiang/generated/l10n.dart'; |
||||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||
import 'package:huixiang/retrofit/data/base_data.dart'; |
||||
import 'package:huixiang/retrofit/data/member_comment_list.dart'; |
||||
import 'package:huixiang/retrofit/retrofit_api.dart'; |
||||
import 'package:huixiang/utils/font_weight.dart'; |
||||
import 'package:huixiang/view_widget/comment_menu.dart'; |
||||
import 'package:huixiang/view_widget/login_tips_dialog.dart'; |
||||
import 'package:huixiang/view_widget/tips_dialog.dart'; |
||||
import 'package:huixiang/web/web_view/input_comment.dart'; |
||||
import 'package:shared_preferences/shared_preferences.dart'; |
||||
|
||||
class CommunityDetails extends StatefulWidget { |
||||
@override |
||||
State<StatefulWidget> createState() { |
||||
return _CommunityDetails(); |
||||
} |
||||
} |
||||
|
||||
class _CommunityDetails extends State<CommunityDetails> { |
||||
double height = 0; |
||||
double commentHeight = 60.h; |
||||
|
||||
List<MemberCommentList> memberList = []; |
||||
ApiService apiService; |
||||
var commentFocus = FocusNode(); |
||||
|
||||
String hintText = S.current.liuxianinjingcaidepinglunba; |
||||
bool isKeyBoardShow = false; |
||||
|
||||
@override |
||||
void didChangeMetrics() { |
||||
WidgetsBinding.instance.addPostFrameCallback((_) { |
||||
if (MediaQuery.of(context).viewInsets.bottom == 0) { |
||||
if (isKeyBoardShow) { |
||||
FocusScope.of(context).requestFocus(FocusNode()); |
||||
setState(() { |
||||
hintText = S.current.liuxianinjingcaidepinglunba; |
||||
isKeyBoardShow = false; |
||||
}); |
||||
} |
||||
} else { |
||||
setState(() { |
||||
isKeyBoardShow = true; |
||||
}); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@override |
||||
void initState() { |
||||
super.initState(); |
||||
|
||||
SharedPreferences.getInstance().then((value) { |
||||
apiService = ApiService( |
||||
Dio(), |
||||
context: context, |
||||
token: value.getString("token"), |
||||
); |
||||
}); |
||||
} |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return Column( |
||||
children: [ |
||||
Expanded( |
||||
child: NestedScrollView( |
||||
headerSliverBuilder: (context, position) { |
||||
return [ |
||||
SliverOverlapAbsorber( |
||||
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), |
||||
sliver: SliverAppBar( |
||||
expandedHeight: (height == 0) ? 614 : height, |
||||
pinned: true, |
||||
backgroundColor: Colors.white, |
||||
title: Text( |
||||
"动态详情", |
||||
style: TextStyle( |
||||
color: Colors.black, |
||||
fontSize: 18.sp, |
||||
fontWeight: MyFontWeight.semi_bold, |
||||
), |
||||
), |
||||
elevation: 0, |
||||
leading: GestureDetector( |
||||
onTap: () { |
||||
Navigator.of(context).pop(); |
||||
}, |
||||
child: Container( |
||||
alignment: Alignment.centerRight, |
||||
margin: EdgeInsets.only(left: 10), |
||||
padding: EdgeInsets.all(6), |
||||
child: Icon( |
||||
Icons.arrow_back_ios, |
||||
color: Colors.black, |
||||
size: 24, |
||||
), |
||||
), |
||||
), |
||||
flexibleSpace: FlexibleSpaceBar( |
||||
//Colors.white, |
||||
background: Container( |
||||
padding: EdgeInsets.only( |
||||
top: MediaQuery.of(context).padding.top + |
||||
kToolbarHeight, |
||||
), |
||||
color: Colors.white, |
||||
child: CommunityDynamic( |
||||
itemCount: 3, |
||||
isDetails: true, |
||||
heightFun: (height) { |
||||
this.height = height + |
||||
MediaQuery.of(context).padding.top + |
||||
kToolbarHeight + |
||||
68; |
||||
setState(() {}); |
||||
}, |
||||
), |
||||
), |
||||
collapseMode: CollapseMode.pin, |
||||
), |
||||
bottom: PreferredSize( |
||||
preferredSize: Size( |
||||
MediaQuery.of(context).size.width, |
||||
46, |
||||
), |
||||
child: Container( |
||||
padding: EdgeInsets.all(16), |
||||
margin: EdgeInsets.only(top: 16.h), |
||||
color: Colors.white, |
||||
child: Row( |
||||
children: [ |
||||
Text( |
||||
S.of(context).pinglun_("1"), |
||||
style: TextStyle( |
||||
fontSize: 14, |
||||
fontWeight: FontWeight.bold, |
||||
color: Color(0xff1A1A1A), |
||||
), |
||||
), |
||||
SizedBox( |
||||
width: 16.w, |
||||
), |
||||
Text( |
||||
S.of(context).xihuan_("0"), |
||||
style: TextStyle( |
||||
fontSize: 14, |
||||
fontWeight: FontWeight.bold, |
||||
color: Color(0xff1A1A1A), |
||||
), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
), |
||||
), |
||||
), |
||||
]; |
||||
}, |
||||
body: Container( |
||||
height: MediaQuery.of(context).size.height - |
||||
MediaQuery.of(context).padding.top + |
||||
kToolbarHeight - |
||||
68, |
||||
margin: EdgeInsets.only(top: 68 + 50 + kToolbarHeight), |
||||
child: Column( |
||||
children: [ |
||||
if (memberList != null && memberList.length > 0) |
||||
ListView.builder( |
||||
shrinkWrap: true, |
||||
physics: NeverScrollableScrollPhysics(), |
||||
itemCount: memberList != null ? memberList.length : 0, |
||||
scrollDirection: Axis.vertical, |
||||
itemBuilder: (context, position) { |
||||
return Material( |
||||
color: Colors.white, |
||||
child: InkWell( |
||||
onTap: () { |
||||
showPressMenu(memberList[position].createUser, |
||||
memberList[position]); |
||||
}, |
||||
child: CommunityComment( |
||||
memberList[position], |
||||
_queryCommentLike, |
||||
), |
||||
), |
||||
); |
||||
}, |
||||
), |
||||
if (memberList != null && memberList.length > 0) |
||||
Container( |
||||
height: commentHeight, |
||||
decoration: BoxDecoration( |
||||
color: Color(0xFFF2F2F2), |
||||
boxShadow: [ |
||||
BoxShadow( |
||||
color: Colors.black.withAlpha(12), |
||||
offset: Offset(0, 2), |
||||
blurRadius: 14, |
||||
spreadRadius: 0, |
||||
), |
||||
], |
||||
), |
||||
alignment: Alignment.topCenter, |
||||
padding: EdgeInsets.only(top: 22.h), |
||||
child: Text( |
||||
S.of(context).yixiansquanbupinglun, |
||||
style: TextStyle( |
||||
fontSize: 12, |
||||
color: Color(0xff353535), |
||||
), |
||||
), |
||||
), |
||||
if (memberList == null || memberList.length == 0) |
||||
Container( |
||||
width: double.infinity, |
||||
alignment: Alignment.topCenter, |
||||
padding: EdgeInsets.all(22.h), |
||||
child: Text( |
||||
S.of(context).zanwupinglun, |
||||
style: TextStyle( |
||||
fontSize: 12, |
||||
fontWeight: FontWeight.bold, |
||||
color: Color(0xFFA0A0A0), |
||||
), |
||||
), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
), |
||||
flex: 1, |
||||
), |
||||
|
||||
/// 富文本评论的输入框 |
||||
InputComment( |
||||
inputKey, |
||||
hintText, |
||||
isKeyBoardShow, |
||||
commentFocus, |
||||
commentTextController, |
||||
_toComment, |
||||
_queryMemberComment, |
||||
_queryInformationLikes, |
||||
), |
||||
], |
||||
); |
||||
} |
||||
|
||||
//给文章/活动点赞 |
||||
_queryInformationLikes() async { |
||||
BaseData baseData = await apiService.informationLikes(""); |
||||
if (baseData != null && baseData.isSuccess) { |
||||
// commentKey.currentState.setState(() {}); |
||||
} else { |
||||
SmartDialog.showToast(baseData.msg, alignment: Alignment.center); |
||||
} |
||||
} |
||||
|
||||
//发布评论 |
||||
_queryMemberComment(String content) async { |
||||
// BaseData baseData = await apiService.memberComment({ |
||||
// "content": content, |
||||
// "parentId": parenId, |
||||
// "relationalId": |
||||
// widget.arguments["activityId"] ?? widget.arguments["articleId"], |
||||
// "relationalType": 1 |
||||
// }).catchError((error) {}); |
||||
// if (baseData != null && baseData.isSuccess) { |
||||
// commentKey.currentState.initState(); |
||||
// commentTextController.text = ""; |
||||
// _toComment(); |
||||
// } |
||||
} |
||||
|
||||
///滑动到评论列表 |
||||
_toComment() { |
||||
// if (commentKey.currentContext == null) return; |
||||
// RenderBox firstRenderBox = commentKey.currentContext.findRenderObject(); |
||||
// Offset first = firstRenderBox.localToGlobal(Offset.zero); |
||||
// scrollController.animateTo(first.dy + scrollController.offset - |
||||
// (kToolbarHeight + MediaQuery.of(context).padding.top), |
||||
// duration: Duration(milliseconds: 300), |
||||
// curve: Curves.easeIn); |
||||
} |
||||
|
||||
final GlobalKey inputKey = GlobalKey(); |
||||
final TextEditingController commentTextController = TextEditingController(); |
||||
|
||||
contentHeight() { |
||||
double contentHeight = MediaQuery.of(context).size.height - |
||||
kToolbarHeight - |
||||
MediaQuery.of(context).padding.top - |
||||
160.h; |
||||
if ((contentHeight - 60.h) > (128.h * memberList.length)) { |
||||
commentHeight = contentHeight - (128.h * memberList.length); |
||||
} |
||||
} |
||||
|
||||
showPressMenu(String userId, memberComment) { |
||||
if (isKeyBoardShow) { |
||||
FocusScope.of(context).requestFocus(FocusNode()); |
||||
return; |
||||
} |
||||
SharedPreferences.getInstance().then((value) { |
||||
SmartDialog.show( |
||||
widget: CommentMenu( |
||||
(type) { |
||||
SmartDialog.dismiss(); |
||||
if (type == "huifu") { |
||||
_reply(memberComment); |
||||
} else if (type == "shanchu") { |
||||
_delCommentTips(); |
||||
} |
||||
}, |
||||
isSelf: userId == value.getString("userId"), |
||||
), |
||||
alignmentTemp: Alignment.bottomCenter, |
||||
isUseAnimationTemp: true, |
||||
animationDurationTemp: Duration(milliseconds: 300), |
||||
); |
||||
}); |
||||
} |
||||
|
||||
///删除评论的提示 |
||||
_delCommentTips() { |
||||
SmartDialog.show(widget: Tips(() { |
||||
delComment(); |
||||
})); |
||||
} |
||||
|
||||
///删除评论 |
||||
delComment() async { |
||||
BaseData baseData = await apiService.delComment(""); |
||||
if (baseData != null && baseData.isSuccess) { |
||||
// commentKey.currentState.initState(); |
||||
} |
||||
} |
||||
|
||||
///评论 回复 |
||||
_reply(memberComment) { |
||||
FocusScope.of(context).requestFocus(commentFocus); |
||||
// parenId = memberComment.id; |
||||
hintText = S.of(context).huifu_("${memberComment.username}"); |
||||
} |
||||
|
||||
//评论点赞 |
||||
_queryCommentLike(String id) async { |
||||
SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); |
||||
String token = sharedPreferences.getString("token"); |
||||
if (token == null || token == "") { |
||||
LoginTipsDialog().show(context); |
||||
return; |
||||
} |
||||
BaseData baseData = await apiService.commentLike(id).catchError((error) {}); |
||||
if (baseData != null && baseData.isSuccess) { |
||||
memberList.forEach((element) { |
||||
if (element.id == id) { |
||||
if (element.liked) { |
||||
element.likes -= 1; |
||||
element.liked = false; |
||||
} else { |
||||
element.likes += 1; |
||||
element.liked = true; |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,201 @@
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:huixiang/generated/l10n.dart'; |
||||
import 'package:huixiang/retrofit/data/base_data.dart'; |
||||
import 'package:huixiang/retrofit/data/member_comment_list.dart'; |
||||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||
import 'package:huixiang/view_widget/custom_image.dart'; |
||||
import 'package:huixiang/view_widget/login_tips_dialog.dart'; |
||||
import 'package:like_button/like_button.dart'; |
||||
import 'package:shared_preferences/shared_preferences.dart'; |
||||
|
||||
|
||||
class CommunityComment extends StatefulWidget { |
||||
|
||||
MemberCommentList memberList; |
||||
Function(String id) queryCommentLike; |
||||
CommunityComment(this.memberList, this.queryCommentLike); |
||||
|
||||
@override |
||||
State<StatefulWidget> createState() { |
||||
return _CommunityComment(); |
||||
} |
||||
|
||||
} |
||||
|
||||
class _CommunityComment extends State<CommunityComment> { |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return Container( |
||||
padding: EdgeInsets.symmetric(vertical: 8.w), |
||||
child: Column( |
||||
children: [ |
||||
Container( |
||||
padding: EdgeInsets.symmetric(horizontal: 16.w), |
||||
child: Row( |
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
||||
crossAxisAlignment: CrossAxisAlignment.center, |
||||
children: [ |
||||
MImage( |
||||
widget.memberList.userAvatarUrl ?? "", |
||||
fit: BoxFit.cover, |
||||
isCircle: true, |
||||
width: 40, |
||||
height: 40, |
||||
fadeSrc: "assets/image/default_user.png", |
||||
errorSrc: "assets/image/default_user.png", |
||||
), |
||||
SizedBox( |
||||
width: 12.w, |
||||
), |
||||
Expanded( |
||||
child: Container( |
||||
// height: 60.h, |
||||
child: Column( |
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
||||
crossAxisAlignment: CrossAxisAlignment.start, |
||||
children: [ |
||||
Text.rich( |
||||
TextSpan( |
||||
children: [ |
||||
TextSpan( |
||||
text: widget.memberList.username, |
||||
style: TextStyle( |
||||
fontWeight: FontWeight.bold, |
||||
fontSize: 12, |
||||
color: Colors.black, |
||||
), |
||||
), |
||||
], |
||||
), |
||||
textDirection: TextDirection.ltr, |
||||
), |
||||
SizedBox( |
||||
height: 3.h, |
||||
), |
||||
Text( |
||||
widget.memberList.createTime, |
||||
overflow: TextOverflow.ellipsis, |
||||
maxLines: 2, |
||||
style: TextStyle( |
||||
fontSize: 14, |
||||
color: Color(0xff808080), |
||||
), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
flex: 1, |
||||
), |
||||
Tooltip( |
||||
message: S.of(context).dianzanxihuan_(S.of(context).pinglun), |
||||
child: Container( |
||||
alignment: Alignment.topRight, |
||||
child: LikeButton( |
||||
padding: EdgeInsets.all(10), |
||||
circleSize: 16, |
||||
circleColor: CircleColor( |
||||
start: Color(0xff00ddff), |
||||
end: Color(0xff0099cc), |
||||
), |
||||
bubblesColor: BubblesColor( |
||||
dotPrimaryColor: Color(0xff33b5e5), |
||||
dotSecondaryColor: Color(0xff0099cc), |
||||
), |
||||
bubblesSize: 15, |
||||
likeBuilder: (bool isLiked) { |
||||
return isLiked |
||||
? Image.asset( |
||||
"assets/image/icon_like.png", |
||||
width: 16, |
||||
height: 16, |
||||
) |
||||
: Image.asset( |
||||
"assets/image/icon_like_h.png", |
||||
width: 16, |
||||
height: 16, |
||||
); |
||||
}, |
||||
isLiked: widget.memberList.liked ?? false, |
||||
onTap: (isLiked) async { |
||||
widget.queryCommentLike(widget.memberList.id); |
||||
return (widget.memberList == null || widget.memberList.liked == null) |
||||
? false |
||||
: widget.memberList.liked; |
||||
}, |
||||
likeCount: widget.memberList.likes, |
||||
countBuilder: (int count, bool isLiked, String text) { |
||||
return Text( |
||||
text, |
||||
style: TextStyle( |
||||
color: Color(0xFF1A1A1A), |
||||
fontSize: 14, |
||||
), |
||||
); |
||||
}, |
||||
), |
||||
), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
Container( |
||||
padding: EdgeInsets.only( |
||||
left: 68.w, |
||||
right: 16.w, |
||||
top: 16.h, |
||||
bottom: 16.h, |
||||
), |
||||
child: Align( |
||||
alignment: Alignment.centerLeft, |
||||
child: Text( |
||||
widget.memberList.content, |
||||
style: TextStyle( |
||||
fontSize: 12, |
||||
color: Color(0xff1A1A1A), |
||||
), |
||||
), |
||||
), |
||||
), |
||||
SizedBox( |
||||
height: 12.h, |
||||
), |
||||
if (widget.memberList.parentContent != null) |
||||
Container( |
||||
margin: EdgeInsets.only(left: 68.w, right: 16.w), |
||||
decoration: BoxDecoration( |
||||
color: Color(0xffF2F2F2), |
||||
borderRadius: BorderRadius.circular(2.0), |
||||
), |
||||
child: Padding( |
||||
padding: EdgeInsets.only(left: 4.w, top: 4.h, bottom: 4.h), |
||||
child: Row( |
||||
mainAxisAlignment: MainAxisAlignment.center, |
||||
crossAxisAlignment: CrossAxisAlignment.start, |
||||
children: [ |
||||
Text( |
||||
"${widget.memberList.parentUserName}:" ?? "", |
||||
style: TextStyle( |
||||
fontSize: 14, |
||||
color: Color(0xff808080), |
||||
), |
||||
), |
||||
Expanded( |
||||
flex: 1, |
||||
child: Text( |
||||
widget.memberList.parentContent ?? "", |
||||
style: TextStyle( |
||||
fontSize: 14, |
||||
color: Color(0xff808080), |
||||
), |
||||
), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
), |
||||
], |
||||
), |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,213 @@
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:flutter_svg/flutter_svg.dart'; |
||||
import 'package:huixiang/utils/font_weight.dart'; |
||||
import 'package:huixiang/view_widget/icon_text.dart'; |
||||
import 'package:huixiang/view_widget/round_button.dart'; |
||||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||
|
||||
class CommunityDynamic extends StatefulWidget { |
||||
|
||||
final int itemCount; |
||||
final Function(double height) heightFun; |
||||
final bool isDetails ; |
||||
|
||||
CommunityDynamic({ |
||||
Key key, |
||||
this.itemCount = 9, |
||||
this.heightFun, |
||||
this.isDetails = false, |
||||
}) : super(key: key); |
||||
|
||||
@override |
||||
State<StatefulWidget> createState() { |
||||
return _CommunityDynamic(); |
||||
} |
||||
} |
||||
|
||||
class _CommunityDynamic extends State<CommunityDynamic> { |
||||
|
||||
GlobalKey globalKey = GlobalKey(); |
||||
double height = 0; |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return Column( |
||||
children: [ |
||||
Container( |
||||
alignment: Alignment.topCenter, |
||||
padding: EdgeInsets.all(16), |
||||
decoration: BoxDecoration( |
||||
color: Colors.white, |
||||
boxShadow: [ |
||||
BoxShadow( |
||||
color: Color(0x08000000), |
||||
offset: Offset(0, 1), |
||||
blurRadius: 8, |
||||
spreadRadius: 0, |
||||
), |
||||
], |
||||
), |
||||
child: Column( |
||||
key: globalKey, |
||||
mainAxisAlignment: MainAxisAlignment.center, |
||||
crossAxisAlignment: CrossAxisAlignment.start, |
||||
mainAxisSize: MainAxisSize.min, |
||||
children: [ |
||||
Row( |
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
||||
crossAxisAlignment: CrossAxisAlignment.center, |
||||
children: [ |
||||
Container( |
||||
height: 44, |
||||
child: Row( |
||||
children: [ |
||||
ClipRRect( |
||||
child: Image.asset( |
||||
"assets/image/default_user.png", |
||||
width: 44, |
||||
height: 44, |
||||
), |
||||
borderRadius: BorderRadius.circular(22), |
||||
), |
||||
SizedBox( |
||||
width: 8, |
||||
), |
||||
Column( |
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
||||
crossAxisAlignment: CrossAxisAlignment.start, |
||||
children: [ |
||||
Text( |
||||
"百花谷", |
||||
style: TextStyle( |
||||
fontSize: 14.sp, |
||||
fontWeight: MyFontWeight.medium, |
||||
color: Color(0xFF1A1A1A), |
||||
), |
||||
), |
||||
Text( |
||||
"2021.04.12", |
||||
style: TextStyle( |
||||
fontSize: 12.sp, |
||||
fontWeight: MyFontWeight.regular, |
||||
color: Color(0xFF808080), |
||||
), |
||||
), |
||||
], |
||||
), |
||||
], |
||||
), |
||||
), |
||||
RoundButton( |
||||
padding: EdgeInsets.symmetric( |
||||
horizontal: 8, |
||||
vertical: 3, |
||||
), |
||||
backgroup: Color(0xFF32A060), |
||||
textColor: Colors.white, |
||||
text: "关注", |
||||
radius: 20, |
||||
icons: SvgPicture.asset( |
||||
"assets/svg/shequ_fabu.svg", |
||||
fit: BoxFit.contain, |
||||
color: Colors.white, |
||||
width: 14, |
||||
height: 14, |
||||
), |
||||
), |
||||
], |
||||
), |
||||
SizedBox( |
||||
height: 12.h, |
||||
), |
||||
Text( |
||||
"文本,是指书面语言的表现形式,从文学角度说,通常是具有完整、系统含义(Message)的一个句子或多个句子的组说,通常是具有完整、系统含义(Message)的一个句子或多个句子的组或多个句子的组说。", |
||||
maxLines: 5, |
||||
overflow: TextOverflow.ellipsis, |
||||
style: TextStyle( |
||||
color: Color(0xFF1A1A1A), |
||||
fontWeight: MyFontWeight.regular, |
||||
fontSize: 14.sp, |
||||
), |
||||
), |
||||
SizedBox( |
||||
height: 16.h, |
||||
), |
||||
if (widget.itemCount == 1) |
||||
Container( |
||||
width: MediaQuery.of(context).size.width / 2, |
||||
height: MediaQuery.of(context).size.width, |
||||
color: Colors.blue.withAlpha(123), |
||||
) |
||||
else |
||||
GridView.builder( |
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( |
||||
crossAxisCount: |
||||
(widget.itemCount == 2 || widget.itemCount == 4) ? 2 : 3, |
||||
crossAxisSpacing: 12.w, |
||||
mainAxisSpacing: 12.w, |
||||
childAspectRatio: 1, |
||||
), |
||||
padding: EdgeInsets.zero, |
||||
shrinkWrap: true, |
||||
physics: NeverScrollableScrollPhysics(), |
||||
itemBuilder: (context, position) { |
||||
return Container( |
||||
color: Colors.blue.withAlpha(123), |
||||
); |
||||
}, |
||||
itemCount: widget.itemCount, |
||||
), |
||||
if (!widget.isDetails) |
||||
SizedBox( |
||||
height: 12.h, |
||||
), |
||||
if (!widget.isDetails) |
||||
Row( |
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
||||
crossAxisAlignment: CrossAxisAlignment.center, |
||||
children: [ |
||||
IconText( |
||||
"58", |
||||
space: 4.w, |
||||
leftImage: "assets/svg/liulanliang.svg", |
||||
iconSize: 16, |
||||
), |
||||
IconText( |
||||
"58", |
||||
space: 4.w, |
||||
leftImage: "assets/svg/pinglun.svg", |
||||
iconSize: 16, |
||||
), |
||||
IconText( |
||||
"58", |
||||
space: 4.w, |
||||
leftImage: "assets/svg/xihuan.svg", |
||||
iconSize: 16, |
||||
), |
||||
], |
||||
), |
||||
], |
||||
), |
||||
), |
||||
Container( |
||||
height: 16, |
||||
color: Color(0xFFF7F7F7), |
||||
) |
||||
], |
||||
); |
||||
} |
||||
|
||||
|
||||
@override |
||||
void didChangeDependencies() { |
||||
WidgetsBinding.instance.addPostFrameCallback(_getContainerHeight); |
||||
super.didChangeDependencies(); |
||||
} |
||||
|
||||
_getContainerHeight(_) { |
||||
height = globalKey.currentContext.size.height; |
||||
widget.heightFun(height); |
||||
print("height: $height"); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,408 @@
|
||||
import 'dart:io'; |
||||
import 'package:dio/dio.dart'; |
||||
import 'package:flutter/cupertino.dart'; |
||||
import 'package:flutter/material.dart'; |
||||
import 'package:flutter_easyloading/flutter_easyloading.dart'; |
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; |
||||
import 'package:flutter_svg/flutter_svg.dart'; |
||||
import 'package:huixiang/generated/l10n.dart'; |
||||
import 'package:huixiang/retrofit/data/base_data.dart'; |
||||
import 'package:huixiang/retrofit/data/upload_result.dart'; |
||||
import 'package:huixiang/retrofit/retrofit_api.dart'; |
||||
import 'package:huixiang/utils/font_weight.dart'; |
||||
import 'package:huixiang/view_widget/my_appbar.dart'; |
||||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||
import 'package:image_pickers/image_pickers.dart'; |
||||
import 'package:shared_preferences/shared_preferences.dart'; |
||||
|
||||
class ReleaseDynamic extends StatefulWidget { |
||||
@override |
||||
State<StatefulWidget> createState() { |
||||
return _ReleaseDynamic(); |
||||
} |
||||
} |
||||
|
||||
class _ReleaseDynamic extends State<ReleaseDynamic> { |
||||
int selectCount = 9; |
||||
List<Medias> mediaPaths = []; |
||||
bool isRelease = false; |
||||
int dynamicType = 0; |
||||
TextEditingController textEditingController = TextEditingController(); |
||||
ApiService apiService; |
||||
|
||||
@override |
||||
void initState() { |
||||
super.initState(); |
||||
|
||||
SharedPreferences.getInstance().then((value) { |
||||
apiService = ApiService( |
||||
Dio(), |
||||
context: context, |
||||
token: value.getString("token"), |
||||
showLoading: false, |
||||
); |
||||
}); |
||||
} |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return Scaffold( |
||||
appBar: MyAppBar( |
||||
title: "写动态", |
||||
titleColor: Colors.black, |
||||
leadingColor: Colors.black, |
||||
background: Colors.white, |
||||
action: Container( |
||||
alignment: Alignment.center, |
||||
child: Container( |
||||
width: 46.w, |
||||
height: 24.h, |
||||
alignment: Alignment.center, |
||||
decoration: BoxDecoration( |
||||
color: isRelease ? Color(0xFF32A060) : Color(0xFFD8D8D8), |
||||
borderRadius: BorderRadius.circular(4), |
||||
), |
||||
child: Text( |
||||
"发布", |
||||
style: TextStyle( |
||||
color: isRelease ? Colors.white : Color(0xFFA0A0A0), |
||||
fontSize: 14.sp, |
||||
fontWeight: MyFontWeight.semi_bold, |
||||
), |
||||
), |
||||
), |
||||
), |
||||
onTap: () { |
||||
if (!isRelease) { |
||||
SmartDialog.showToast("请输入您此刻的想法!~"); |
||||
return; |
||||
} |
||||
releaseDynamic(); |
||||
}, |
||||
), |
||||
body: Container( |
||||
child: Column( |
||||
children: [ |
||||
buildEdit(), |
||||
GridView.builder( |
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( |
||||
crossAxisCount: 3, |
||||
crossAxisSpacing: 12.w, |
||||
mainAxisSpacing: 12.w, |
||||
childAspectRatio: 1, |
||||
), |
||||
padding: EdgeInsets.all(16), |
||||
shrinkWrap: true, |
||||
physics: NeverScrollableScrollPhysics(), |
||||
itemBuilder: (context, position) { |
||||
if (mediaPaths.length > position) { |
||||
return imageItem(mediaPaths[position]); |
||||
} else { |
||||
return addImageItem(); |
||||
} |
||||
}, |
||||
itemCount: (mediaPaths.length == 0) |
||||
? 1 |
||||
: ((dynamicType == 2) |
||||
? 1 |
||||
: mediaPaths.length >= 9 |
||||
? 9 |
||||
: (mediaPaths.length + 1)), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
); |
||||
} |
||||
|
||||
releaseDynamic() async { |
||||
String dynamicText = textEditingController.text; |
||||
if (dynamicText == null || dynamicText == "") { |
||||
SmartDialog.showToast("请输入您此刻的想法!~"); |
||||
return; |
||||
} |
||||
EasyLoading.show(status: S.of(context).zhengzaijiazai); |
||||
|
||||
fileUpload().then((value) async { |
||||
String subjectType = "text"; |
||||
if (dynamicType == 0) { |
||||
subjectType = "text"; |
||||
} else if (dynamicType == 1) { |
||||
subjectType = "image"; |
||||
} else if (dynamicType == 2) { |
||||
subjectType = "video"; |
||||
} |
||||
|
||||
List<String> remoteImageUrls = []; |
||||
String remoteVideoUrl = ""; |
||||
if (mediaPaths.length > 0) { |
||||
if (dynamicType == 1) { |
||||
remoteImageUrls = mediaPaths.map((e) => e.remotePath).toList(); |
||||
} else if (dynamicType == 2) { |
||||
remoteVideoUrl = mediaPaths[0].remotePath; |
||||
} |
||||
} |
||||
|
||||
BaseData<String> baseData = await apiService.trend({ |
||||
"images": remoteImageUrls, |
||||
"subject": dynamicText, |
||||
"subjectType": subjectType, |
||||
"video": remoteVideoUrl, |
||||
}).catchError((onError) { |
||||
EasyLoading.dismiss(); |
||||
}); |
||||
if (baseData.isSuccess) {} |
||||
EasyLoading.dismiss(); |
||||
}); |
||||
} |
||||
|
||||
///文件上传 |
||||
Future<void> fileUpload() async { |
||||
if (mediaPaths != null && mediaPaths.length > 0) { |
||||
await Future.forEach(mediaPaths, (element) async { |
||||
if ((element.remotePath == null || element.remotePath == "") && |
||||
(element != null && |
||||
element.path != null && |
||||
element.path != "" && |
||||
await File(element.path).exists())) { |
||||
BaseData<UploadResult> baseData = await apiService.upload( |
||||
File(element.path), |
||||
123123123, |
||||
); |
||||
if (baseData != null && baseData.isSuccess) { |
||||
UploadResult uploadResult = baseData.data; |
||||
mediaPaths[mediaPaths.indexOf(element)].remotePath = uploadResult.url; |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
} |
||||
|
||||
Widget imageItem(Medias media) { |
||||
return InkWell( |
||||
onTap: () { |
||||
showDeletePicker(media); |
||||
}, |
||||
child: Container( |
||||
decoration: BoxDecoration( |
||||
borderRadius: BorderRadius.circular(4), |
||||
), |
||||
alignment: Alignment.center, |
||||
child: ClipRRect( |
||||
borderRadius: BorderRadius.circular(4), |
||||
child: Image.file( |
||||
File(media.galleryMode == GalleryMode.video |
||||
? media.thumbPath |
||||
: media.path), |
||||
fit: BoxFit.cover, |
||||
width: double.infinity, |
||||
height: double.infinity, |
||||
), |
||||
), |
||||
), |
||||
); |
||||
} |
||||
|
||||
///显示图片选择方式 |
||||
showImagePicker() { |
||||
if (dynamicType == 1) { |
||||
getImageOrVideo(GalleryMode.image); |
||||
return; |
||||
} |
||||
showCupertinoModalPopup( |
||||
context: context, |
||||
builder: (context) { |
||||
return CupertinoActionSheet( |
||||
title: Text("选择媒体文件"), |
||||
actions: [ |
||||
CupertinoActionSheetAction( |
||||
child: Text("照片"), |
||||
onPressed: () { |
||||
getImageOrVideo(GalleryMode.image); |
||||
Navigator.of(context).pop(); |
||||
}, |
||||
isDefaultAction: true, |
||||
isDestructiveAction: false, |
||||
), |
||||
CupertinoActionSheetAction( |
||||
child: Text("视频"), |
||||
onPressed: () { |
||||
getImageOrVideo(GalleryMode.video); |
||||
Navigator.of(context).pop(); |
||||
}, |
||||
isDefaultAction: true, |
||||
isDestructiveAction: false, |
||||
), |
||||
], |
||||
cancelButton: CupertinoActionSheetAction( |
||||
onPressed: () { |
||||
Navigator.of(context).pop(); |
||||
}, |
||||
child: Text(S.of(context).quxiao), |
||||
isDestructiveAction: true, |
||||
), |
||||
); |
||||
}); |
||||
} |
||||
|
||||
///显示图片选择方式 |
||||
showDeletePicker(Medias media) { |
||||
showCupertinoModalPopup( |
||||
context: context, |
||||
builder: (context) { |
||||
return CupertinoActionSheet( |
||||
title: Text("动态"), |
||||
actions: [ |
||||
CupertinoActionSheetAction( |
||||
child: Text("删除"), |
||||
onPressed: () { |
||||
mediaPaths.remove(media); |
||||
if (mediaPaths.length == 0) { |
||||
dynamicType = 0; |
||||
} |
||||
selectCount = 9 - mediaPaths.length; |
||||
Navigator.of(context).pop(); |
||||
setState(() {}); |
||||
}, |
||||
isDefaultAction: true, |
||||
isDestructiveAction: false, |
||||
), |
||||
], |
||||
cancelButton: CupertinoActionSheetAction( |
||||
onPressed: () { |
||||
Navigator.of(context).pop(); |
||||
}, |
||||
child: Text(S.of(context).quxiao), |
||||
isDestructiveAction: true, |
||||
), |
||||
); |
||||
}); |
||||
} |
||||
|
||||
Widget addImageItem() { |
||||
return InkWell( |
||||
onTap: () { |
||||
showImagePicker(); |
||||
}, |
||||
child: Container( |
||||
decoration: BoxDecoration( |
||||
color: Color(0xFFF2F2F2), |
||||
borderRadius: BorderRadius.circular(4), |
||||
), |
||||
alignment: Alignment.center, |
||||
child: Column( |
||||
mainAxisAlignment: MainAxisAlignment.center, |
||||
crossAxisAlignment: CrossAxisAlignment.center, |
||||
children: [ |
||||
SvgPicture.asset( |
||||
"assets/svg/zhaopianshipin.svg", |
||||
width: 48, |
||||
height: 48, |
||||
fit: BoxFit.contain, |
||||
), |
||||
Text( |
||||
"照片/视频", |
||||
style: TextStyle( |
||||
fontWeight: MyFontWeight.semi_bold, |
||||
fontSize: 15.sp, |
||||
color: Color(0xFFCDCCCC), |
||||
), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
); |
||||
} |
||||
|
||||
Future getImageOrVideo(GalleryMode galleryMode) async { |
||||
if (selectCount == 0) return; |
||||
List<Media> medias = await ImagePickers.pickerPaths( |
||||
galleryMode: galleryMode, |
||||
selectCount: (galleryMode == GalleryMode.video) ? 1 : selectCount, |
||||
showGif: true, |
||||
showCamera: false, |
||||
compressSize: 500, |
||||
uiConfig: UIConfig( |
||||
uiThemeColor: Color(0xFFFFFFFF), |
||||
), |
||||
cropConfig: CropConfig( |
||||
enableCrop: false, |
||||
width: 200, |
||||
height: 200, |
||||
), |
||||
); |
||||
|
||||
mediaPaths.addAll(medias.map((e) => Medias(e)).toList()); |
||||
selectCount = 9 - mediaPaths.length; |
||||
|
||||
if (mediaPaths.length > 0) { |
||||
if (galleryMode == GalleryMode.image) { |
||||
dynamicType = 1; |
||||
} else { |
||||
dynamicType = 2; |
||||
} |
||||
} |
||||
|
||||
setState(() {}); |
||||
} |
||||
|
||||
///动态输入框 |
||||
Widget buildEdit() { |
||||
return Container( |
||||
height: 174.h, |
||||
margin: EdgeInsets.symmetric(horizontal: 16.w), |
||||
decoration: BoxDecoration( |
||||
border: Border( |
||||
bottom: BorderSide( |
||||
width: 1.w, |
||||
color: Color(0xFFD8D8D8), |
||||
style: BorderStyle.solid, |
||||
), |
||||
), |
||||
), |
||||
child: TextField( |
||||
controller: textEditingController, |
||||
style: TextStyle( |
||||
fontSize: 14.sp, |
||||
fontWeight: MyFontWeight.medium, |
||||
color: Color(0xFF4C4C4C), |
||||
), |
||||
onChanged: (text) { |
||||
bool release = text != "" && text != null; |
||||
if (release != isRelease) { |
||||
isRelease = release; |
||||
setState(() {}); |
||||
} |
||||
}, |
||||
decoration: InputDecoration( |
||||
contentPadding: EdgeInsets.symmetric( |
||||
vertical: 18.h, |
||||
), |
||||
errorBorder: InputBorder.none, |
||||
focusedBorder: InputBorder.none, |
||||
enabledBorder: InputBorder.none, |
||||
hintText: "此时此刻的想法~", |
||||
hintStyle: TextStyle( |
||||
fontSize: 14.sp, |
||||
color: Color(0xFFA29E9E), |
||||
), |
||||
), |
||||
), |
||||
); |
||||
} |
||||
} |
||||
|
||||
class Medias { |
||||
// Media media; |
||||
|
||||
Medias(Media media) { |
||||
this.thumbPath = media.thumbPath; |
||||
this.path = media.path; |
||||
this.galleryMode = media.galleryMode; |
||||
} |
||||
|
||||
String thumbPath; |
||||
String path; |
||||
GalleryMode galleryMode; |
||||
String remotePath; |
||||
} |
Loading…
Reference in new issue