Hibok
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1036 lines
32 KiB

  1. import 'package:cached_network_image/cached_network_image.dart';
  2. import 'package:chat/data/UserData.dart';
  3. import 'package:chat/data/constants.dart';
  4. import 'package:chat/generated/i18n.dart';
  5. import 'package:chat/home/MyDialogContent.dart';
  6. import 'package:chat/home/SelectPage.dart';
  7. import 'package:chat/utils/CustomUI.dart';
  8. import 'package:chat/utils/HttpUtil.dart';
  9. import 'package:chat/utils/MessageMgr.dart';
  10. import 'package:chat/utils/screen.dart';
  11. import 'package:dio/dio.dart';
  12. import 'package:flutter/material.dart';
  13. import 'package:city_pickers/city_pickers.dart';
  14. import 'package:flutter/services.dart';
  15. import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
  16. import 'package:image_cropper/image_cropper.dart';
  17. import 'package:oktoast/oktoast.dart';
  18. import '../utils/ShadowButton.dart';
  19. import 'package:image_picker/image_picker.dart';
  20. import 'dart:io';
  21. import '../data/UserData.dart';
  22. import '../utils/TokenMgr.dart';
  23. import '../data/WebData.dart';
  24. import 'IndexPage.dart';
  25. import 'UserAgreement.dart';
  26. const double TipLeft = 20;
  27. const double BorderLeft = 25;
  28. const double LeftTextFontSize = 13;
  29. const LetfTextStyle = TextStyle(
  30. fontSize: LeftTextFontSize,
  31. fontWeight: FontWeight.w600,
  32. color: Constants.BlackTextColor);
  33. class EditPage extends StatefulWidget {
  34. @required
  35. final bool isEditPage;
  36. EditPage({Key key, this.isEditPage = false}) : super(key: key);
  37. _EditPageState createState() => _EditPageState();
  38. }
  39. class _EditPageState extends State<EditPage> {
  40. //职业
  41. String profession = '';
  42. Set<String> professionId = Set.from([
  43. UserData().basicInfo.occupation == null
  44. ? 'Information-Internet'
  45. : UserData().basicInfo.occupation
  46. ]);
  47. //国家
  48. String country = '';
  49. Set<String> countryId = Set.from([
  50. UserData().basicInfo.country == null
  51. ? 'Country-VietNam'
  52. : 'Country-${UserData().basicInfo.country}'
  53. ]);
  54. //期待对象
  55. String lovePeople = '';
  56. Set<String> lovePeopleId = Set.from(UserData().basicInfo.hopeObject == null
  57. ? ['Indifferent']
  58. : UserData().basicInfo.hopeObject.split(','));
  59. //是否展示社交账号
  60. bool isHiddenSocialAccount = UserData().basicInfo.accountStatus == 1;
  61. //昵称
  62. String nickname = UserData().basicInfo.nickName;
  63. //约会范围
  64. String dateRange = '';
  65. Set<String> dateRangeId = Set.from(UserData().basicInfo.meetPlace == null
  66. ? []
  67. : UserData().basicInfo.meetPlace.split(','));
  68. //生日
  69. String birthday = '';
  70. String birthdayId = UserData().basicInfo.birthday == null
  71. ? '1995-01-01'
  72. : UserData().basicInfo.birthday;
  73. //身高数据
  74. String heightStr = '';
  75. String heightId = UserData().basicInfo.height == null
  76. ? '0'
  77. : UserData().basicInfo.height.toInt().toString();
  78. //体重数据
  79. String weightStr = '';
  80. String weightId = UserData().basicInfo.weight == null
  81. ? '0'
  82. : UserData().basicInfo.weight.toInt().toString();
  83. //是否同意用户协议
  84. bool isAgree = false;
  85. File headFile;
  86. bool loadSuccess = false;
  87. String wechat = UserData().basicInfo.wechat;
  88. String facebook = UserData().basicInfo.facebook;
  89. TextEditingController nickNameController =
  90. new TextEditingController(text: UserData().basicInfo.nickName);
  91. TextEditingController mymsgController =
  92. new TextEditingController(text: UserData().basicInfo.ownMsg);
  93. TextEditingController wechatController =
  94. new TextEditingController(text: UserData().basicInfo.wechat);
  95. TextEditingController fbController =
  96. new TextEditingController(text: UserData().basicInfo.facebook);
  97. initValue() {
  98. if (!loadSuccess) {
  99. profession = WebData().getProffesionName(professionId.first);
  100. if (!widget.isEditPage) {
  101. switch (UserData().language) {
  102. case LanguageType.English:
  103. countryId = Set.from(['Country-UnitedStates']);
  104. break;
  105. case LanguageType.Vietnamese:
  106. countryId = Set.from(['Country-VietNam']);
  107. break;
  108. case LanguageType.TraditionalChinese:
  109. case LanguageType.TraditionalChinese:
  110. countryId = Set.from(['Country-China']);
  111. break;
  112. case LanguageType.Korean:
  113. countryId = Set.from(['Country-Korea']);
  114. break;
  115. case LanguageType.Japanese:
  116. countryId = Set.from(['Country-Japan']);
  117. break;
  118. default:
  119. }
  120. }
  121. country = WebData().getCountry(countryId.first.split('-')[1]);
  122. var hopeObject = '';
  123. lovePeopleId.forEach((f) => hopeObject += hopeObject == '' ? f : ',$f');
  124. lovePeople = WebData().getLovePeople(hopeObject);
  125. var dateRangeStr = '';
  126. dateRangeId
  127. .forEach((f) => dateRangeStr += dateRangeStr == '' ? f : ',$f');
  128. dateRange = WebData().getDateRange(dateRangeStr);
  129. birthday = birthdayId;
  130. heightStr = (UserData().basicInfo.height == 0.0 ||
  131. UserData().basicInfo.height == null)
  132. ? I18n.of(context).not_show
  133. : '${UserData().basicInfo.height.toInt()}CM';
  134. weightStr = (UserData().basicInfo.weight == 0.0 ||
  135. UserData().basicInfo.weight == null)
  136. ? I18n.of(context).not_show
  137. : '${UserData().basicInfo.weight.toInt()}KG';
  138. loadSuccess = true;
  139. setState(() {});
  140. }
  141. }
  142. BoxDecoration _getCardDecoration() {
  143. return new BoxDecoration(
  144. color: Colors.white,
  145. border: Border(
  146. top: Constants.GreyBorderSide, bottom: Constants.GreyBorderSide));
  147. }
  148. @override
  149. void initState() {
  150. super.initState();
  151. MessageMgr().on('change_currentcity', changeCurrentcity);
  152. print('EditPage initState');
  153. }
  154. changeCurrentcity(data) {
  155. if (!widget.isEditPage && dateRangeId.length == 0) {
  156. var dateRangeStr = '';
  157. dateRangeId = Set.from([UserData().currentCity]);
  158. dateRangeId
  159. .forEach((f) => dateRangeStr += dateRangeStr == '' ? f : ',$f');
  160. dateRange = WebData().getDateRange(dateRangeStr);
  161. setState(() {});
  162. }
  163. }
  164. @override
  165. void dispose() {
  166. nickNameController.dispose();
  167. mymsgController.dispose();
  168. MessageMgr().on('change_currentcity', changeCurrentcity);
  169. super.dispose();
  170. }
  171. _showDialog() {
  172. CustomUI.buildOneConfirm(
  173. context, I18n.of(context).exit_registration, I18n.of(context).determine,
  174. () {
  175. HttpUtil().clearCacheData();
  176. Navigator.of(context).pushAndRemoveUntil(new MaterialPageRoute(
  177. builder: (context) {
  178. return IndexPage();
  179. },
  180. ), (route) => route == null);
  181. });
  182. }
  183. Future<bool> _requestPop() {
  184. if (!widget.isEditPage) {
  185. _showDialog();
  186. } else {
  187. Navigator.of(context).pop();
  188. }
  189. return new Future.value(false);
  190. }
  191. @override
  192. Widget build(BuildContext context) {
  193. initValue();
  194. var keyHeight = MediaQuery.of(context).viewInsets.bottom;
  195. if (keyHeight > 0) {
  196. UserData().setKeyboardHeight(keyHeight);
  197. }
  198. Widget appBar = new AppBar(
  199. backgroundColor: AppColors.NewAppbarBgColor,
  200. title: new Text(
  201. widget.isEditPage
  202. ? I18n.of(context).edit_information
  203. : I18n.of(context).complete_material,
  204. textScaleFactor: 1.0,
  205. style: TextStyle(color: AppColors.NewAppbarTextColor),
  206. ),
  207. elevation: 1,
  208. leading: CustomUI.buildCustomLeading(context),
  209. actions: <Widget>[
  210. widget.isEditPage
  211. ? Container(
  212. alignment: Alignment.center,
  213. child: new InkWell(
  214. child: new Padding(
  215. padding: EdgeInsets.only(
  216. right: 15, left: 15, top: 10, bottom: 10),
  217. child: new Text(
  218. I18n.of(context).save,
  219. textScaleFactor: 1.0,
  220. style: TextStyle(color: Constants.BlueTextColor),
  221. ),
  222. ),
  223. onTap: () {
  224. postSettion((data) {
  225. showToast(I18n.of(context).successfully_saved);
  226. Navigator.of(context).pop();
  227. MessageMgr().emit('update_data', data);
  228. });
  229. },
  230. ),
  231. )
  232. : Container(),
  233. ],
  234. centerTitle: true);
  235. return WillPopScope(
  236. onWillPop: _requestPop,
  237. child: Scaffold(
  238. backgroundColor: const Color(0xFFEDEDED),
  239. body: SafeArea(
  240. child: Center(
  241. child: Container(
  242. height: MediaQuery.of(context).size.height,
  243. width: MediaQuery.of(context).size.width,
  244. child: _buildBody(),
  245. ),
  246. )),
  247. appBar: appBar,
  248. ));
  249. }
  250. Widget _buildBody() {
  251. List<Widget> body = [
  252. _buildHeadUrl(),
  253. _buildBasicData(context),
  254. UserData().isMan() ? Container() : _buildSocialContact(),
  255. // _buildHiddenButtom(),
  256. // _buildMoreInfo(),
  257. _buildCommitButton(),
  258. ];
  259. List<Widget> body2 = [
  260. _buildBasicData(context),
  261. _buildSocialContact(),
  262. _buildHiddenButtom(),
  263. _buildMoreInfo(),
  264. ];
  265. return new ListView(
  266. children: widget.isEditPage ? body2 : body,
  267. );
  268. }
  269. Widget _buildCommitButton() {
  270. return new Column(
  271. children: <Widget>[
  272. _buildRegisterButton(),
  273. _buildAgreement(),
  274. ],
  275. );
  276. }
  277. Widget _buildAgreement() {
  278. return InkWell(
  279. onTap: () async {
  280. Navigator.of(context).push(
  281. new MaterialPageRoute(
  282. builder: (context) {
  283. return UserAgreement();
  284. },
  285. ),
  286. );
  287. },
  288. child: Container(
  289. margin: EdgeInsets.only(top: 10, bottom: 20, left: 10, right: 10),
  290. child: Text(
  291. I18n.of(context).agreed_agreement,
  292. style: TextStyle(color: Colors.red),
  293. textAlign: TextAlign.center,
  294. )));
  295. }
  296. postSettion(callback) async {
  297. if (nickname == null || nickname == "" || nickname.length > 25) {
  298. showToast(I18n.of(context).only1_8);
  299. return;
  300. }
  301. if (dateRangeId.length == 0 && UserData().hasLocationPermission) {
  302. showToast(I18n.of(context).Please_select_a_resident_city);
  303. return;
  304. }
  305. if (birthdayId == null || birthdayId == '0') {
  306. showToast(I18n.of(context).choose_birthday);
  307. return;
  308. }
  309. if (professionId.length == 0) {
  310. showToast(I18n.of(context).choose_career);
  311. return;
  312. }
  313. // if (dateItemId.length == 0) {
  314. // showToast(I18n.of(context).select_program);
  315. // return;
  316. // }
  317. if (countryId.length == 0) {
  318. showToast(I18n.of(context).select_program);
  319. return;
  320. }
  321. if (lovePeopleId.length == 0) {
  322. showToast(I18n.of(context).choose_lover);
  323. return;
  324. }
  325. if (!UserData().isMan() &&
  326. (wechat == null || wechat == '') &&
  327. (facebook == null || facebook == '')) {
  328. showToast(I18n.of(context).least_account);
  329. return;
  330. }
  331. var program = '';
  332. //dateItemId.forEach((f) => program += program == '' ? f : ',$f');
  333. var hopeObject = '';
  334. lovePeopleId.forEach((f) => hopeObject += hopeObject == '' ? f : ',$f');
  335. var dateRangeStr = '';
  336. dateRangeId.forEach((f) => dateRangeStr += dateRangeStr == '' ? f : ',$f');
  337. Map data = {
  338. "userId": UserData().basicInfo.userId,
  339. "nickName": nickname,
  340. "birthday": birthdayId,
  341. };
  342. data['sign'] = TokenMgr().getSign(data);
  343. data["occupation"] = professionId.first;
  344. data["program"] = program;
  345. data["hopeObject"] = hopeObject;
  346. data["height"] = heightId;
  347. data['Country'] = countryId.first.split('-')[1];
  348. data["weight"] = weightId;
  349. data["ownMsg"] = mymsgController.text;
  350. data["meetPlace"] = dateRangeStr;
  351. data['wxAccount'] = wechat;
  352. data['fbAccount'] = facebook;
  353. data['accountStatus'] = isHiddenSocialAccount ? 1 : 0;
  354. data["lat"] = UserData().latitude;
  355. data["lng"] = UserData().longitude;
  356. try {
  357. Response res = await HttpUtil()
  358. .post('user/complete/material', data: data, isShowLoading: true);
  359. Map resData = res.data;
  360. if (resData['code'] == 0) {
  361. UserData().basicInfo.ownMsg = mymsgController.text;
  362. callback(mymsgController.text);
  363. } else {
  364. showToast(resData['msg']);
  365. }
  366. } catch (e) {}
  367. }
  368. //构建注册按钮
  369. Widget _buildRegisterButton() {
  370. Text text =
  371. fixedText(I18n.of(context).submit, fontSize: 15, color: Colors.white);
  372. LinearGradient gradientColor = new LinearGradient(colors: <Color>[
  373. Constants.ConfrimButtonColor,
  374. Constants.ConfrimButtonColor,
  375. ]);
  376. callback() {
  377. postSettion((data) async {
  378. Navigator.of(context)
  379. .pushNamedAndRemoveUntil('/main', (route) => route == null);
  380. });
  381. }
  382. return new Container(
  383. margin: EdgeInsets.only(top: 20),
  384. height: 44,
  385. width: MediaQuery.of(context).size.width * 0.85,
  386. child: ShadowButton().builder(gradientColor, text, callback),
  387. );
  388. }
  389. //自定义item
  390. Widget _bottomBorderBox(String textLeft, String textRight, bool flag,
  391. controller, bool isInit, callback,
  392. {inputFormatters}) {
  393. Widget left = Container(
  394. width: 90,
  395. margin: EdgeInsets.only(right: 10),
  396. child: Text(
  397. textLeft,
  398. textScaleFactor: 1.0,
  399. style: LetfTextStyle,
  400. ));
  401. Widget right = flag
  402. ? Expanded(
  403. child: TextField(
  404. keyboardAppearance: Brightness.light,
  405. controller: controller,
  406. style: TextStyle(
  407. fontSize: 14, textBaseline: TextBaseline.alphabetic),
  408. decoration: InputDecoration(
  409. contentPadding: EdgeInsets.zero,
  410. hintText: textRight,
  411. hintStyle: TextStyle(
  412. fontSize: 14,
  413. color: Constants.LightGreyTextColor,
  414. fontWeight: FontWeight.normal),
  415. border: InputBorder.none,
  416. ),
  417. maxLines: 1,
  418. inputFormatters: inputFormatters,
  419. onChanged: (str) {
  420. if (flag && callback != null) callback(str);
  421. },
  422. ),
  423. )
  424. : Expanded(
  425. child: Text(
  426. textRight,
  427. textScaleFactor: 1.0,
  428. style: TextStyle(
  429. fontSize: 14,
  430. color: !isInit
  431. ? Constants.LightGreyTextColor
  432. : Constants.BlackTextColor),
  433. ),
  434. );
  435. var icon = !flag
  436. ? Padding(
  437. padding: EdgeInsets.only(right: 7),
  438. child: Icon(
  439. IconData(0xe63c, fontFamily: 'iconfont'),
  440. size: 20.0,
  441. color: Color(AppColors.TabIconNormal),
  442. ))
  443. : Container();
  444. return new InkWell(
  445. highlightColor: Colors.transparent,
  446. radius: 0.0,
  447. onTap: () {
  448. if (!flag && callback != null) callback();
  449. },
  450. child: Container(
  451. height: 53,
  452. margin: EdgeInsets.only(left: BorderLeft, bottom: 0),
  453. child: new Row(
  454. children: <Widget>[left, right, icon],
  455. ),
  456. ));
  457. }
  458. //下划线
  459. Widget _buildDivider() {
  460. return new Container(
  461. margin: EdgeInsets.zero,
  462. padding: EdgeInsets.zero,
  463. height: 1,
  464. width: MediaQuery.of(context).size.width,
  465. child: new Divider(
  466. color: Colors.grey[300],
  467. ),
  468. );
  469. }
  470. //基本数据
  471. Widget _buildBasicData(context) {
  472. Widget tip = CustomUI.buildTopTip(
  473. BorderLeft, I18n.of(context).basic_information,
  474. showStar: true);
  475. //选择约会地区
  476. void selectDateRange() async {
  477. print(WebData().provinces['China']);
  478. Navigator.of(context).push(
  479. new MaterialPageRoute(
  480. builder: (context) {
  481. return SelectPage(
  482. mostNum: 1,
  483. dataId: dateRangeId,
  484. title: I18n.of(context).Resident_city,
  485. provinces: UserData().isInChina
  486. ? {'China': WebData().provinces['China']}
  487. : {
  488. 'VietNam': WebData().provinces['VietNam'],
  489. },
  490. cities: WebData().cities,
  491. isSingle: true,
  492. callback: (tempRankId) {
  493. if (tempRankId.length == 0) return;
  494. dateRangeId = tempRankId.toSet();
  495. if (dateRangeId.length != 0) {
  496. dateRange = '';
  497. dateRangeId.forEach((item) {
  498. var city = item.split('-');
  499. dateRange += dateRange == ''
  500. ? WebData().cities[city[0]][city[1]]
  501. : '/${WebData().cities[city[0]][city[1]]}';
  502. });
  503. }
  504. Navigator.of(context).pop();
  505. },
  506. );
  507. },
  508. ),
  509. );
  510. }
  511. //选择生日
  512. void selectDate() async {
  513. var locale;
  514. switch (UserData().language) {
  515. case LanguageType.English:
  516. locale = LocaleType.en;
  517. break;
  518. case LanguageType.Vietnamese:
  519. locale = LocaleType.vi;
  520. break;
  521. case LanguageType.TraditionalChinese:
  522. case LanguageType.SimplifiedChinese:
  523. locale = LocaleType.zh;
  524. break;
  525. case LanguageType.Korean:
  526. locale = LocaleType.ko;
  527. break;
  528. case LanguageType.Japanese:
  529. locale = LocaleType.jp;
  530. break;
  531. default:
  532. locale = LocaleType.en;
  533. }
  534. var list = [];
  535. if (birthdayId != null) list = birthdayId.split('-');
  536. var nowDate;
  537. nowDate = list.length == 3
  538. ? DateTime(int.parse(list[0]), int.parse(list[1]), int.parse(list[2]))
  539. : DateTime(1990, 1, 1);
  540. DatePicker.showDatePicker(context,
  541. showTitleActions: true,
  542. minTime: DateTime(1900, 3, 5),
  543. maxTime: DateTime(DateTime.now().year - 18, 1, 1),
  544. onChanged: (date) {}, onConfirm: (date) {
  545. birthday = '${date.year}-${date.month}-${date.day}';
  546. birthdayId = '${date.year}-${date.month}-${date.day}';
  547. setState(() {});
  548. }, currentTime: nowDate, locale: locale);
  549. }
  550. //选择职业
  551. void selectProfession() async {
  552. Navigator.of(context).push(
  553. new MaterialPageRoute(
  554. builder: (context) {
  555. return SelectPage(
  556. mostNum: 4,
  557. dataId: professionId,
  558. provinces: WebData().professionCate,
  559. isSingle: true,
  560. cities: WebData().professionList,
  561. title: I18n.of(context).choose_career,
  562. callback: (Set tempRankId) {
  563. professionId = tempRankId.toSet();
  564. if (professionId.length != 0) {
  565. profession = '';
  566. professionId.forEach((item) {
  567. var city = item.split('-');
  568. profession += profession == ''
  569. ? WebData().professionList[city[0]][city[1]]
  570. : '/${WebData().professionList[city[0]][city[1]]}';
  571. });
  572. }
  573. Navigator.of(context).pop();
  574. },
  575. );
  576. },
  577. ),
  578. );
  579. }
  580. //选择国家
  581. void selectCountry() async {
  582. Navigator.of(context).push(
  583. new MaterialPageRoute(
  584. builder: (context) {
  585. return SelectPage(
  586. mostNum: 4,
  587. dataId: countryId,
  588. title: I18n.of(context).country,
  589. provinces: {'Country': I18n.of(context).country},
  590. cities: {'Country': WebData().provinces},
  591. isSingle: true,
  592. callback: (tempRankId) {
  593. countryId = tempRankId.toSet();
  594. print('countryID ${countryId.length}');
  595. if (countryId.length != 0) {
  596. country = '';
  597. countryId.forEach((item) {
  598. var city = item.split('-');
  599. country += country == ''
  600. ? WebData().provinces[city[1]]
  601. : '/${WebData().provinces[city[1]]}';
  602. });
  603. }
  604. Navigator.of(context).pop();
  605. },
  606. );
  607. },
  608. ),
  609. );
  610. }
  611. //选择期待对象
  612. void selectLovePeople() {
  613. var tempSet = lovePeopleId.toSet();
  614. List<Widget> actions = [
  615. FlatButton(
  616. child: fixedText(I18n.of(context).close),
  617. onPressed: () {
  618. tempSet.clear();
  619. Navigator.of(context).pop();
  620. },
  621. ),
  622. FlatButton(
  623. child: fixedText(I18n.of(context).determine),
  624. onPressed: () {
  625. Navigator.of(context).pop();
  626. setState(() {
  627. lovePeopleId = tempSet.toSet();
  628. if (lovePeopleId.length != 0) {
  629. lovePeople = '';
  630. lovePeopleId.forEach((k) {
  631. lovePeople += (lovePeople == '')
  632. ? WebData().loverPeopleMap[k]
  633. : ('/' + WebData().loverPeopleMap[k]);
  634. });
  635. }
  636. });
  637. },
  638. ),
  639. ];
  640. //约会节目
  641. showDialog(
  642. context: context,
  643. builder: (BuildContext context) {
  644. return AlertDialog(
  645. title: new Align(
  646. alignment: Alignment.center,
  647. child: Text(I18n.of(context).expect_lover),
  648. ),
  649. content: new MyDialogContent(
  650. mostNum: 4,
  651. dataMap: WebData().loverPeopleMap,
  652. keyList: tempSet,
  653. ),
  654. contentPadding: EdgeInsets.only(top: 10),
  655. actions: actions,
  656. );
  657. });
  658. }
  659. Widget idItem = new InkWell(
  660. highlightColor: Colors.transparent,
  661. radius: 0.0,
  662. onTap: () {},
  663. child: Container(
  664. height: 53,
  665. margin: EdgeInsets.only(left: BorderLeft, bottom: 0),
  666. child: new Row(
  667. children: <Widget>[
  668. Container(
  669. width: 90,
  670. margin: EdgeInsets.only(right: 10),
  671. child: Text(
  672. 'ID',
  673. textScaleFactor: 1.0,
  674. style: LetfTextStyle,
  675. )),
  676. Text(
  677. UserData().basicInfo.userId.toString(),
  678. textScaleFactor: 1.0,
  679. style: TextStyle(fontSize: 14, color: Constants.GreyTextColor),
  680. )
  681. ],
  682. ),
  683. ));
  684. List<Widget> basicList = [
  685. widget.isEditPage ? idItem : Container(),
  686. _buildDivider(),
  687. _bottomBorderBox(I18n.of(context).nickname, I18n.of(context).fill_out,
  688. true, nickNameController, true, (str) => nickname = str,
  689. inputFormatters: [
  690. LengthLimitingTextInputFormatter(Constants.NameLength)
  691. ]),
  692. _buildDivider(),
  693. _bottomBorderBox(I18n.of(context).country, country, false, null,
  694. countryId.length != 0, selectCountry),
  695. _buildDivider(),
  696. _bottomBorderBox(
  697. I18n.of(context).Resident_city,
  698. !UserData().hasLocationPermission
  699. ? I18n.of(context).unknown
  700. : dateRange,
  701. false,
  702. null,
  703. dateRangeId.length != 0,
  704. UserData().hasLocationPermission ? selectDateRange : null),
  705. _buildDivider(),
  706. _bottomBorderBox(I18n.of(context).birthday, birthday, false, null,
  707. birthdayId != null, selectDate),
  708. _buildDivider(),
  709. _bottomBorderBox(I18n.of(context).job, profession, false, null,
  710. professionId.length != 0, selectProfession),
  711. // _bottomBorderBox(I18n.of(context).country, dateItem, false, null,
  712. // dateItemId.length != 0, selectCountry),
  713. _buildDivider(),
  714. _bottomBorderBox(I18n.of(context).expect_lover, lovePeople, false, null,
  715. lovePeopleId.length != 0, selectLovePeople),
  716. ];
  717. Widget basicCard = new Container(
  718. color: Colors.white,
  719. child: new Column(
  720. children: basicList,
  721. ),
  722. );
  723. return new Column(
  724. children: <Widget>[
  725. tip,
  726. basicCard,
  727. ],
  728. );
  729. }
  730. //社交账号
  731. Widget _buildSocialContact() {
  732. Widget tip = CustomUI.buildTopTip(
  733. BorderLeft, I18n.of(context).social_account,
  734. showStar: !UserData().isMan());
  735. List<Widget> basicList = [
  736. _bottomBorderBox(
  737. I18n.of(context).wechat_number,
  738. I18n.of(context).fill_out,
  739. true,
  740. wechatController,
  741. true,
  742. (str) => wechat = str,
  743. inputFormatters: [
  744. //WhitelistingTextInputFormatter(RegExp("^[A-Za-z0-9]+\$")),
  745. LengthLimitingTextInputFormatter(20)
  746. ]),
  747. _buildDivider(),
  748. _bottomBorderBox(I18n.of(context).facebook, I18n.of(context).fill_out,
  749. true, fbController, true, (str) => facebook = str,
  750. inputFormatters: [
  751. //WhitelistingTextInputFormatter(RegExp("^[A-Za-z0-9]+\$")),
  752. LengthLimitingTextInputFormatter(20)
  753. ]),
  754. ];
  755. Widget socialCard = new Container(
  756. color: Colors.white,
  757. child: new Column(
  758. children: basicList,
  759. ),
  760. );
  761. return new Column(
  762. children: <Widget>[tip, socialCard],
  763. );
  764. }
  765. Widget _buildHeadUrl() {
  766. double width = 95;
  767. return Container(
  768. color: Colors.white,
  769. padding: EdgeInsets.only(top: 20, bottom: 10),
  770. child: Column(
  771. children: <Widget>[
  772. InkWell(
  773. onTap: () {
  774. _sendPicture();
  775. },
  776. child: Container(
  777. width: width,
  778. height: width,
  779. child: ClipRRect(
  780. borderRadius: BorderRadius.circular(6.0),
  781. child: uploadImageUrl == null
  782. ? Image.asset(Constants.DefaultHeadImgUrl,
  783. height: width, width: width)
  784. // : Image.file(headFile, height: width, width: width),
  785. : CachedNetworkImage(
  786. imageUrl: uploadImageUrl,
  787. placeholder: CustomUI.buildImgLoding,
  788. width: width,
  789. height: width,
  790. ),
  791. ),
  792. ),
  793. ),
  794. Padding(
  795. padding: EdgeInsets.only(top: 5),
  796. child: InkWell(
  797. onTap: () {
  798. _sendPicture();
  799. },
  800. child: fixedText(
  801. I18n.of(context).upload_avatar,
  802. color: Constants.BlackTextColor,
  803. ),
  804. )),
  805. ],
  806. ),
  807. );
  808. }
  809. void _sendPicture() async {
  810. if (await CustomUI.showPhotoPermissionSetting(context)) {
  811. var tempFile = await ImagePicker.pickImage(source: ImageSource.gallery);
  812. if (tempFile != null) {
  813. //裁剪图片
  814. _cropPicture(tempFile);
  815. }
  816. }
  817. }
  818. String uploadImageUrl;
  819. void _cropPicture(tempFile) async {
  820. File croppedFile = await ImageCropper.cropImage(
  821. sourcePath: tempFile.path,
  822. aspectRatio: CropAspectRatio(ratioX: 1, ratioY: 1),
  823. );
  824. uploadImageUrl = null;
  825. if (croppedFile != null) {
  826. headFile = croppedFile;
  827. Map data = {"type": 1, "userId": UserData().basicInfo.userId};
  828. data['sign'] = TokenMgr().getSign(data);
  829. Response response = await HttpUtil()
  830. .uploadFile(headFile, data, 'upload/file/postflie', 'image');
  831. var resData = response.data;
  832. if (resData['code'] == 0 && resData['msg'] != null) {
  833. setState(() {
  834. uploadImageUrl = resData['msg'];
  835. });
  836. } else {
  837. showToast(I18n.of(context).fail);
  838. }
  839. setState(() {});
  840. } else {
  841. print('裁剪失败---');
  842. }
  843. }
  844. //是否隐藏社交账号
  845. Widget _buildHiddenButtom() {
  846. Widget left = Text(
  847. I18n.of(context).hide_account1,
  848. textScaleFactor: 1.0,
  849. style: TextStyle(fontSize: LeftTextFontSize, fontWeight: FontWeight.w500),
  850. );
  851. Widget right = new Expanded(
  852. child: Container(
  853. margin: EdgeInsets.only(right: 20),
  854. alignment: Alignment.centerRight,
  855. child: new Switch(
  856. activeTrackColor: Constants.ConfrimButtonColor.withOpacity(0.3),
  857. value: isHiddenSocialAccount,
  858. onChanged: (bool val) {
  859. setState(() {
  860. isHiddenSocialAccount = !isHiddenSocialAccount;
  861. });
  862. },
  863. )));
  864. return new Container(
  865. decoration: _getCardDecoration(),
  866. margin: EdgeInsets.only(top: 15, bottom: 0),
  867. padding: EdgeInsets.only(left: BorderLeft),
  868. height: 53,
  869. child: new Row(
  870. children: <Widget>[left, right],
  871. ),
  872. );
  873. }
  874. //更多信息
  875. Widget _buildMoreInfo() {
  876. Widget tip =
  877. CustomUI.buildTopTip(BorderLeft, I18n.of(context).more_information);
  878. //选择升高
  879. void selectHeight() async {
  880. Result temp = await CityPickers.showCityPicker(
  881. context: context,
  882. showType: ShowType.p,
  883. provincesData: WebData().heightData,
  884. citiesData: WebData().heightListData,
  885. height: 280,
  886. );
  887. setState(() {
  888. if (temp == null) return;
  889. heightStr = "${temp.provinceName}";
  890. heightId = temp.provinceId;
  891. });
  892. }
  893. //选择升高
  894. void selectWeight() async {
  895. Result temp = await CityPickers.showCityPicker(
  896. context: context,
  897. showType: ShowType.p,
  898. provincesData: WebData().weightData,
  899. citiesData: WebData().weightListData,
  900. height: 280,
  901. );
  902. setState(() {
  903. if (temp == null) return;
  904. weightStr = "${temp.provinceName}";
  905. weightId = temp.provinceId;
  906. });
  907. }
  908. //个人介绍框
  909. var myselfBox = Container(
  910. margin: EdgeInsets.only(left: BorderLeft, bottom: 0),
  911. child: Row(
  912. crossAxisAlignment: CrossAxisAlignment.start,
  913. children: <Widget>[
  914. Container(
  915. width: 90,
  916. margin: EdgeInsets.only(top: 14),
  917. child: Text(
  918. I18n.of(context).self_introduction,
  919. textScaleFactor: 1.0,
  920. style: LetfTextStyle,
  921. )),
  922. Expanded(
  923. child: TextField(
  924. keyboardAppearance: Brightness.light,
  925. controller: mymsgController,
  926. style: TextStyle(
  927. fontSize: 14,
  928. color: Constants.BlackTextColor,
  929. textBaseline: TextBaseline.alphabetic),
  930. decoration: InputDecoration(
  931. contentPadding:
  932. EdgeInsets.only(top: 14, right: 10, bottom: 10, left: 10),
  933. hintText: I18n.of(context).introduce_yourself,
  934. hintStyle: TextStyle(fontSize: 14, color: Colors.grey),
  935. border: InputBorder.none,
  936. ),
  937. maxLines: 5,
  938. inputFormatters: [LengthLimitingTextInputFormatter(50)],
  939. ),
  940. )
  941. ],
  942. ),
  943. );
  944. List<Widget> basicList = [
  945. _bottomBorderBox(I18n.of(context).height, heightStr, false, null,
  946. heightId != '0', selectHeight),
  947. _buildDivider(),
  948. _bottomBorderBox(I18n.of(context).weight, weightStr, false, null,
  949. weightId != '0', selectWeight),
  950. _buildDivider(),
  951. myselfBox,
  952. ];
  953. Widget socialCard = new Container(
  954. color: Colors.white,
  955. child: new Column(
  956. children: basicList,
  957. ),
  958. );
  959. return new Column(
  960. children: <Widget>[tip, socialCard],
  961. );
  962. }
  963. }