Hibok
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

383 Zeilen
13 KiB

  1. import 'package:cached_network_image/cached_network_image.dart';
  2. import 'package:chat/data/WebData.dart';
  3. import 'package:chat/data/constants.dart';
  4. import 'package:chat/generated/i18n.dart';
  5. import 'package:chat/home/ProfilePage.dart';
  6. import 'package:chat/utils/IconToggle.dart';
  7. import 'package:chat/utils/MessageMgr.dart';
  8. import 'package:chat/utils/UserChips.dart';
  9. import 'package:chat/utils/screen.dart';
  10. import 'package:flutter/material.dart';
  11. import 'package:oktoast/oktoast.dart';
  12. import '../utils/HttpUtil.dart';
  13. import 'package:dio/dio.dart';
  14. import "../data/UserData.dart";
  15. import '../utils/TokenMgr.dart';
  16. class UserCard extends StatelessWidget {
  17. final String userName;
  18. final bool isReal;
  19. final String city; //城市
  20. final int age; //年龄
  21. final String constellation; //星座
  22. final String professional; //职业
  23. final String isOnline;
  24. final double distance;
  25. final int userId;
  26. final bool isLove;
  27. final bool isBalck;
  28. final String headUrl;
  29. final bool payImg;
  30. final int imgNum;
  31. final int sex;
  32. final bool isHidden;
  33. final int member;
  34. final bool hiddenDistince;
  35. final int nameSize;
  36. UserCard(
  37. {Key key,
  38. this.userName,
  39. this.isReal: false,
  40. this.city,
  41. this.age,
  42. this.constellation,
  43. this.professional,
  44. this.isOnline,
  45. this.distance,
  46. this.userId,
  47. this.isLove: false,
  48. this.sex,
  49. this.headUrl: '',
  50. this.payImg: false,
  51. this.imgNum: 0,
  52. this.isHidden: false,
  53. this.member: 0,
  54. this.hiddenDistince: false,
  55. this.nameSize = 8,
  56. this.isBalck: false})
  57. : super(key: key);
  58. @override
  59. Widget build(BuildContext context) {
  60. bool isVIP = member > 0;
  61. bool isSVIP = member == 2;
  62. //头像
  63. Widget headImg() {
  64. double height = 69.4;
  65. return Stack(
  66. children: <Widget>[
  67. Container(
  68. height: height,
  69. width: height,
  70. child: ClipRRect(
  71. borderRadius: BorderRadius.circular(10),
  72. child: headUrl == '' || headUrl == null
  73. ? Image.asset(
  74. Constants.DefaultHeadImgUrl,
  75. )
  76. : CachedNetworkImage(
  77. imageUrl: headUrl,
  78. placeholder: (context, url) => Image.asset(
  79. Constants.DefaultHeadImgUrl,
  80. width: height,
  81. height: height,
  82. ),
  83. fit: BoxFit.cover,
  84. )),
  85. ),
  86. Positioned(
  87. left: 0,
  88. bottom: 0,
  89. child: Container(
  90. height: 15,
  91. width: 40,
  92. decoration: BoxDecoration(
  93. color: Colors.black54,
  94. borderRadius: BorderRadius.only(
  95. bottomLeft: Radius.circular(10),
  96. topRight: Radius.circular(10))),
  97. child: Row(
  98. //mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  99. children: <Widget>[
  100. Padding(
  101. padding: EdgeInsets.only(left: 6),
  102. child:
  103. Icon(Icons.image, size: 12, color: Colors.white)),
  104. Padding(
  105. padding: EdgeInsets.only(left: 5, top: 2),
  106. child: fixedText(imgNum.toString(),
  107. color: Colors.white, fontSize: 12),
  108. ),
  109. ],
  110. ),
  111. ))
  112. ],
  113. );
  114. }
  115. //名字以及认证状态
  116. Widget nameState() {
  117. return Row(
  118. children: <Widget>[
  119. fixedText(WebData().subUserName(userName, size: nameSize),
  120. fontSize: 15),
  121. isReal && sex == 2
  122. ? Container(
  123. margin: EdgeInsets.only(left: 5),
  124. padding:
  125. EdgeInsets.only(top: 2, bottom: 2, left: 5, right: 5),
  126. alignment: Alignment.center,
  127. decoration: BoxDecoration(
  128. borderRadius: BorderRadius.circular(10),
  129. color: Constants.PurpleBackgroundColor,
  130. ),
  131. child: fixedText('Real', fontSize: 8, color: Colors.white))
  132. : Container(),
  133. isVIP && sex == 1
  134. ? Container(
  135. margin: EdgeInsets.only(left: 5),
  136. child: isSVIP ? Constants.svipIcon : Constants.vipIcon)
  137. : Container(),
  138. ],
  139. );
  140. }
  141. //距离、在线以及相册
  142. Widget otherWidget() {
  143. var greyColor = const Color(0xFFB2B2B2);
  144. return Row(
  145. children: <Widget>[
  146. InfoTile(
  147. icon: IconData(0xe630, fontFamily: Constants.IconFontFamily),
  148. title: hiddenDistince
  149. ? I18n.of(context).secrecy
  150. : (UserData().hasLocationPermission
  151. ? WebData().getDistanceString(distance)
  152. : I18n.of(context).unknown),
  153. titleColor: greyColor,
  154. isDivider: true),
  155. InfoTile(
  156. title: isOnline,
  157. titleColor: greyColor,
  158. isDivider: payImg || isHidden),
  159. isHidden
  160. ? InfoTile(
  161. icon: IconData(0xe645, fontFamily: 'iconfont'),
  162. iconHeight: 22,
  163. title: I18n.of(context).application_view,
  164. titleColor: greyColor,
  165. isDivider: false,
  166. onTap: () {
  167. print('click');
  168. })
  169. : Container(),
  170. payImg
  171. ? InfoTile(
  172. icon: IconData(0xe632, fontFamily: Constants.IconFontFamily),
  173. title: I18n.of(context).paid_photo,
  174. titleColor: greyColor,
  175. isDivider: false,
  176. onTap: () {
  177. print('click');
  178. })
  179. : Container(),
  180. ],
  181. );
  182. }
  183. return InkWell(
  184. onTap: () {
  185. // if (sex == UserData().basicInfo.sex) {
  186. // showToast(UserData().basicInfo.sex == 1
  187. // ? I18n.of(context).cant_see
  188. // : I18n.of(context).cant_see2);
  189. // return;
  190. // }
  191. Navigator.of(context).push(
  192. new MaterialPageRoute(
  193. builder: (context) {
  194. return ProfilePage(
  195. userId: userId,
  196. );
  197. },
  198. ),
  199. );
  200. },
  201. child: Column(
  202. children: <Widget>[
  203. Container(
  204. //背景
  205. padding: EdgeInsets.only(left: 18, top: 14.5, bottom: 14.5),
  206. color: Colors.white,
  207. child: Stack(
  208. children: <Widget>[
  209. Row(
  210. children: <Widget>[
  211. //头像图片
  212. Padding(
  213. padding:
  214. EdgeInsets.only(right: 16.5, top: 5, bottom: 5),
  215. child: headImg()),
  216. //信息
  217. Container(
  218. width: MediaQuery.of(context).size.width - 104,
  219. child: Column(
  220. crossAxisAlignment: CrossAxisAlignment.start,
  221. mainAxisAlignment: MainAxisAlignment.end,
  222. children: <Widget>[
  223. nameState(), //名字以及状态
  224. //用户的信息标记
  225. Padding(padding: EdgeInsets.only(top: 9)),
  226. UserChips(
  227. city: city,
  228. age: age,
  229. constellation: constellation,
  230. professional: professional),
  231. Padding(padding: EdgeInsets.only(top: 4)),
  232. otherWidget(),
  233. ],
  234. )),
  235. ],
  236. ),
  237. Positioned(
  238. child: //赞
  239. sex == UserData().basicInfo.sex
  240. ? InkWell(
  241. onTap: () {
  242. showToast(UserData().isMan()
  243. ? I18n.of(context).not_love
  244. : I18n.of(context).not_love2);
  245. },
  246. child: Container(
  247. padding: EdgeInsets.only(
  248. left: 15, right: 15, bottom: 15),
  249. child: Icon(
  250. IconData(
  251. 0xe625,
  252. fontFamily: Constants.IconFontFamily,
  253. ),
  254. size: 15,
  255. color: Constants.GreyTextColor,
  256. )))
  257. : IconToggle(
  258. key: key,
  259. icon: IconData(
  260. 0xe625,
  261. fontFamily: Constants.IconFontFamily,
  262. ),
  263. activeIcon: IconData(
  264. 0xe623,
  265. fontFamily: Constants.IconFontFamily,
  266. ),
  267. defaultColor: Constants.GreyTextColor,
  268. activeColor: Constants.RedTextColor,
  269. isActive: isLove,
  270. size: 16,
  271. onTap: (bool isActive) async {
  272. if (isActive) {
  273. HttpUtil().setLove(userId, () {
  274. MessageMgr().emit('refresh_love_list',
  275. {'UserId': userId, 'flag': 0});
  276. });
  277. } else {
  278. HttpUtil().cancleLove(userId, () {
  279. MessageMgr().emit('refresh_love_list',
  280. {'UserId': userId, 'flag': 2});
  281. });
  282. }
  283. }),
  284. right: 0,
  285. top: 1,
  286. )
  287. ],
  288. )),
  289. Container(
  290. color: Colors.white,
  291. padding: EdgeInsets.only(
  292. left: Screen.width * 0.1, right: Screen.width * 0.1),
  293. child: Divider(
  294. height: 1,
  295. color: Constants.DividerLineColor,
  296. ),
  297. )
  298. ],
  299. ));
  300. }
  301. }
  302. const double TileHeight = 14;
  303. class InfoTile extends StatelessWidget {
  304. @required
  305. final String title;
  306. final Color titleColor;
  307. final IconData icon;
  308. final double iconHeight;
  309. final VoidCallback onTap;
  310. final bool isDivider;
  311. const InfoTile(
  312. {Key key,
  313. this.title,
  314. this.titleColor,
  315. this.icon,
  316. this.onTap,
  317. this.iconHeight: TileHeight,
  318. this.isDivider = false})
  319. : super(key: key);
  320. @override
  321. Widget build(BuildContext context) {
  322. List<Widget> elements = [];
  323. if (icon != null) {
  324. elements.add(Padding(
  325. padding: EdgeInsets.only(bottom: 2),
  326. child: Icon(icon, size: TileHeight, color: titleColor)));
  327. }
  328. elements.add(
  329. Container(
  330. alignment: Alignment.bottomCenter,
  331. constraints: BoxConstraints(minHeight: 17),
  332. padding: EdgeInsets.only(right: 5, bottom: 1.5),
  333. child: Text(title,
  334. textScaleFactor: 1.0,
  335. style: TextStyle(
  336. fontSize: 11,
  337. color: titleColor,
  338. fontWeight: FontWeight.normal))),
  339. );
  340. if (isDivider) {
  341. elements.add(Container(
  342. height: 16,
  343. child: VerticalDivider(
  344. width: 1,
  345. indent: 0,
  346. endIndent: 0,
  347. color: Colors.black26,
  348. )));
  349. }
  350. var tileWidget = Container(
  351. padding: EdgeInsets.only(right: 5),
  352. child: Row(
  353. //crossAxisAlignment: CrossAxisAlignment.start,
  354. children: elements,
  355. ));
  356. if (onTap != null) {
  357. return InkWell(
  358. child: tileWidget,
  359. onTap: onTap,
  360. );
  361. } else {
  362. return tileWidget;
  363. }
  364. }
  365. }