Hibok
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

755 satır
26 KiB

  1. import 'dart:async';
  2. import 'dart:ffi';
  3. import 'package:chat/data/UserData.dart';
  4. import 'package:chat/data/translate_hk_data_mgr.dart';
  5. import 'package:chat/models/group_info_model.dart';
  6. import 'package:chat/models/money_change.dart';
  7. import 'package:chat/utils/MessageMgr.dart';
  8. import 'package:chat/utils/msgHandler.dart';
  9. import 'package:chat/utils/screen.dart';
  10. import 'package:chat/utils/sp_utils.dart';
  11. import 'package:flutter/cupertino.dart';
  12. import 'package:flutter/material.dart';
  13. import 'package:flutter/services.dart';
  14. import 'package:provider/provider.dart';
  15. import '../../data/constants.dart';
  16. import '../../generated/i18n.dart';
  17. import '../../r.dart';
  18. import '../../utils/CustomUI.dart';
  19. import 'package:chat/utils/PopUpMenu.dart' as myPop;
  20. class TranslationButlerPage extends StatefulWidget {
  21. final GroupInfoModel groupInfoModel;
  22. TranslationButlerPage({Key key, this.groupInfoModel}) : super(key: key);
  23. @override
  24. State<StatefulWidget> createState() {
  25. return TranslationButlerPageState();
  26. }
  27. }
  28. class ValueModel{
  29. String name;
  30. var key;
  31. ValueModel(this.name,this.key);
  32. }
  33. class TranslationButlerPageState extends State<TranslationButlerPage> {
  34. int curToLang = 1;
  35. int curSourceLang = UserData().language;
  36. int curScenes = 0;
  37. List<ValueModel> langList; ///语言列表
  38. List<ValueModel> scenesList; ///场景列表
  39. String extraMsg='';
  40. FocusNode focusNode = new FocusNode();
  41. String textLimitTips='';
  42. ScrollController _scrollController = new ScrollController();
  43. int orderStatus = 0; ///订单状态
  44. int secondsPassed = 1;///等待时间计数
  45. int timeStamp; ///订单开始时间戳
  46. Timer waitTimer;///等待时间计时器
  47. int time60=1; ///60秒一圈计数
  48. int waitNum=0;
  49. refreshOrder(args){
  50. orderStatus = TranslateHKMgr().orderStatus;
  51. switch(orderStatus){
  52. case TranslateHKMgr.ORDER_STATUS_EMPTY:
  53. isCreatingOrder=false;
  54. waitTimer?.cancel();
  55. secondsPassed = 0;
  56. SPUtils.save(Constants.TranslationHelper,null);
  57. break;
  58. case TranslateHKMgr.ORDER_STATUS_WAITING:
  59. secondsPassed = 0;
  60. waitNum = TranslateHKMgr().waitNum;
  61. waitTimer = Timer.periodic(Duration(seconds: 1), (Timer t) {
  62. handleTick();
  63. });
  64. break;
  65. }
  66. setState(() {});
  67. }
  68. ///订单没有人接,超时,服务器会发送取消订单通知
  69. cancelOrder(args){
  70. TranslateHKMgr().orderStatus = TranslateHKMgr.ORDER_STATUS_EMPTY;
  71. refreshOrder(null);
  72. }
  73. @override
  74. void initState() {
  75. super.initState();
  76. orderStatus = TranslateHKMgr().orderStatus;
  77. waitNum = TranslateHKMgr().waitNum;
  78. initData();
  79. MessageMgr().on(MessageMgr.TRANSLATE_HK_REFRESH_ORDER, refreshOrder);
  80. MessageMgr().on(MessageMgr.TRANSLATE_HK_CANCEL_ORDER, cancelOrder);
  81. WidgetsBinding.instance.addPostFrameCallback((_) {
  82. // Future.delayed(Duration(seconds: 1), () {
  83. //// CustomUI.buildTranslationHelperOrderDialog(context,true);
  84. // Navigator.of(context).push(
  85. // new MaterialPageRoute(
  86. // builder: (context) {
  87. // return ChatPage(
  88. // key: Key('Chat'),
  89. // friendId: 100029,
  90. // isTranslateButler: true,
  91. // );
  92. // },
  93. // ),
  94. // );
  95. // });
  96. });
  97. }
  98. initData() async {
  99. String time = (await SPUtils.get(Constants.TranslationHelper));
  100. if (time != null) {
  101. print('time:$time');
  102. int second = int.parse(time) ~/ 1000;
  103. if((DateTime.now().millisecondsSinceEpoch ~/ 1000 - second)>8*3600){ ///超过5小时清除缓存记录
  104. SPUtils.save(Constants.TranslationHelper,null);
  105. return;
  106. }
  107. secondsPassed =
  108. ((DateTime.now().millisecondsSinceEpoch ~/ 1000 - second));
  109. } else {
  110. print('time: null');
  111. }
  112. }
  113. bool isCreatingOrder=false;
  114. apply() {
  115. if(isCreatingOrder){
  116. return;
  117. }
  118. isCreatingOrder=true;
  119. TranslateHKMgr().startWaitTime=DateTime.now().millisecondsSinceEpoch;
  120. MsgHandler.sendCreateTranslateOrder(langList[curSourceLang].key,langList[curToLang].key,scenesList[curScenes].key,extraMsg);
  121. extraMsg='';
  122. }
  123. @override
  124. void didChangeDependencies() {
  125. super.didChangeDependencies();
  126. textLimitTips = I18n.of(context).translation_input_limit.replaceAll('/s1', '80');
  127. langList = [
  128. ValueModel(I18n.of(context).english,1),
  129. ValueModel(I18n.of(context).Vietnamese,2),
  130. ValueModel(I18n.of(context).traditional_Chinese,4),
  131. ValueModel(I18n.of(context).Simplified_Chinese,8),
  132. ValueModel(I18n.of(context).Korean,16),
  133. ValueModel(I18n.of(context).Japanese,32),
  134. ];
  135. scenesList = [
  136. ValueModel(I18n.of(context).translation_scenes_1,0),
  137. ValueModel(I18n.of(context).translation_scenes_2,1),
  138. ValueModel(I18n.of(context).translation_scenes_3,2),
  139. ValueModel(I18n.of(context).translation_scenes_4,3),
  140. ];
  141. }
  142. @override
  143. void dispose() {
  144. waitTimer?.cancel();
  145. MessageMgr().off(MessageMgr.TRANSLATE_HK_REFRESH_ORDER, refreshOrder);
  146. MessageMgr().off(MessageMgr.TRANSLATE_HK_CANCEL_ORDER, cancelOrder);
  147. if (orderStatus==TranslateHKMgr.ORDER_STATUS_WAITING && timeStamp != null) {
  148. print('保存时间戳$timeStamp');
  149. SPUtils.save(Constants.TranslationHelper, timeStamp.toString());
  150. }
  151. super.dispose();
  152. }
  153. _langPopMenu(bool isSource) {
  154. var curIndex = isSource ? curSourceLang : curToLang;
  155. return myPop.PopupMenuButton(
  156. child: Container(
  157. height: 37,
  158. width: double.maxFinite,
  159. decoration: BoxDecoration(
  160. color: Color(0xffD3E7FF),
  161. borderRadius: BorderRadius.circular(5)),
  162. child: Row(
  163. mainAxisAlignment: MainAxisAlignment.start,
  164. children: <Widget>[
  165. Expanded(
  166. child: Container(padding: EdgeInsets.only(left: 5),alignment: Alignment.center,child: Text(
  167. langList[curIndex].name,
  168. textAlign: TextAlign.center,
  169. overflow: TextOverflow.ellipsis,
  170. textScaleFactor: 1.0,
  171. style: TextStyle(color: Color(0xff4A5E76), fontSize: 14),
  172. ),)),
  173. Icon(IconData(0xe63b, fontFamily: Constants.IconFontFamily),
  174. size: 30, color: Color(0xff4A5E76))
  175. ],
  176. ),
  177. ),
  178. offset: Offset(0, 100),
  179. onSelected: (int index) {
  180. if (curIndex != index) {
  181. if (isSource) {
  182. curSourceLang = index;
  183. } else {
  184. curToLang = index;
  185. }
  186. print('更换翻译语言');
  187. setState(() {});
  188. }
  189. },
  190. itemBuilder: (BuildContext context) {
  191. return List<myPop.PopupMenuItem<int>>.generate(langList.length,
  192. (int i) {
  193. return myPop.PopupMenuItem(
  194. child: Container(
  195. alignment: Alignment.center,
  196. color: Colors.white,
  197. padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
  198. child: Text(langList[i].name,
  199. textScaleFactor: 1.0,
  200. maxLines: 1,
  201. style: TextStyle(
  202. color: i == curIndex
  203. ? Colors.blueAccent
  204. : Color(AppColors.AppBarColor),
  205. fontSize: 14)),
  206. ),
  207. value: i,
  208. );
  209. });
  210. });
  211. }
  212. _scenesPopMenu() {
  213. var curIndex = curScenes;
  214. return myPop.PopupMenuButton(
  215. child: Container(
  216. height: 40,
  217. width: double.maxFinite,
  218. decoration:BoxDecoration(
  219. borderRadius: BorderRadius.all(Radius.circular(6)),
  220. color: Colors.white,
  221. boxShadow: [
  222. BoxShadow(
  223. color: Color(0x739f9f9f),
  224. offset: Offset(0.2, 0.4),
  225. blurRadius: 1.0,
  226. spreadRadius: 0.6),
  227. // BoxShadow(
  228. // color: Color(0x9900FF00), offset: Offset(1.0, 1.0)),
  229. // BoxShadow(color: Color(0xFF0000FF))
  230. ]),
  231. child: Row(
  232. mainAxisAlignment: MainAxisAlignment.start,
  233. children: <Widget>[
  234. Expanded(
  235. child: Text(
  236. scenesList[curIndex].name,
  237. textAlign: TextAlign.center,
  238. overflow: TextOverflow.ellipsis,
  239. textScaleFactor: 1.0,
  240. style: TextStyle(color: Color(0xff3875E9), fontSize: 14),
  241. )),
  242. Icon(IconData(0xe63b, fontFamily: Constants.IconFontFamily),
  243. size: 30, color: Color(0xff4A5E76))
  244. ],
  245. ),
  246. ),
  247. offset: Offset(0, 100),
  248. onSelected: (int index) {
  249. if (curIndex != index) {
  250. curScenes = index;
  251. print('更换场景');
  252. setState(() {});
  253. }
  254. },
  255. itemBuilder: (BuildContext context) {
  256. return List<myPop.PopupMenuItem<int>>.generate(scenesList.length,
  257. (int i) {
  258. return myPop.PopupMenuItem(
  259. child: Container(
  260. width: Screen.width *0.43,
  261. alignment: Alignment.center,
  262. color: Colors.white,
  263. padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
  264. child: Text(scenesList[i].name,
  265. textScaleFactor: 1.0,
  266. maxLines: 1,
  267. style: TextStyle(
  268. color: i == curIndex
  269. ? Colors.blueAccent
  270. : Color(AppColors.AppBarColor),
  271. fontSize: 14)),
  272. ),
  273. value: i,
  274. );
  275. });
  276. });
  277. }
  278. @override
  279. Widget build(BuildContext context) {
  280. Widget appBar = AppBar(
  281. backgroundColor: AppColors.NewAppbarBgColor,
  282. title: Text(
  283. I18n.of(context).translation_butler,
  284. textScaleFactor: 1.0,
  285. style: TextStyle(color: AppColors.NewAppbarTextColor),
  286. ),
  287. // leading: CustomUI.buildCustomLeading(context),
  288. centerTitle: true,
  289. actions: <Widget>[
  290. Container(
  291. child: CustomUI.buildImageLabel(R.assetsImagesCoin,
  292. Provider.of<MoneyChangeProvider>(context).money,
  293. isLeft: true),
  294. decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
  295. ),
  296. SizedBox(
  297. width: 10,
  298. )
  299. ],
  300. );
  301. return Scaffold(
  302. appBar: appBar,
  303. body: SafeArea(
  304. child: Container(
  305. color: Color(0xffE8EAF0),
  306. child: orderStatus==TranslateHKMgr.ORDER_STATUS_EMPTY ? createOrderPage() : waitPage(),
  307. ),
  308. ),
  309. );
  310. }
  311. Widget createOrderPage() {
  312. return ListView(
  313. controller: _scrollController,
  314. children: <Widget>[
  315. Padding(
  316. padding: EdgeInsets.only(left: 20, right: 10, top: 15),
  317. child: Text(
  318. I18n.of(context).translation_butler_tips,
  319. textScaleFactor: 1.0,
  320. style: TextStyle(color: Color(0xffABABAB), fontSize: 13),
  321. ),
  322. ),
  323. Container(
  324. margin: EdgeInsets.all(10),
  325. child: Card(
  326. elevation: 2, // 阴影
  327. shape: RoundedRectangleBorder(
  328. borderRadius: BorderRadius.circular(10),
  329. // side: BorderSide(color: Colors.green,width: 25),
  330. ),
  331. child: Container(
  332. padding: EdgeInsets.all(10),
  333. child: Column(
  334. crossAxisAlignment: CrossAxisAlignment.start,
  335. children: <Widget>[
  336. Padding(
  337. padding: EdgeInsets.only(bottom: 12),
  338. child: Text(
  339. I18n.of(context).choose_language,
  340. textScaleFactor: 1.0,
  341. textAlign: TextAlign.left,
  342. style: TextStyle(
  343. color: AppColors.NewAppbarTextColor, fontSize: 17),
  344. ),
  345. ),
  346. Row(
  347. children: <Widget>[
  348. SizedBox(width: 15,),
  349. Expanded(
  350. child: _langPopMenu(true),
  351. flex: 5,
  352. ),
  353. Expanded(
  354. child: InkWell(
  355. onTap: () {
  356. var temp = curSourceLang;
  357. curSourceLang = curToLang;
  358. curToLang = temp;
  359. setState(() {});
  360. },
  361. child: Container(
  362. child: Icon(
  363. IconData(
  364. 0xe669,
  365. fontFamily: Constants.IconFontFamily,
  366. ),
  367. size: 24,
  368. color: Color(0xff4A5E76),
  369. ),
  370. padding: EdgeInsets.symmetric(
  371. vertical: 5, horizontal: 5),
  372. ),
  373. ),
  374. flex: 2,
  375. ),
  376. Expanded(
  377. child: _langPopMenu(false),
  378. flex: 5,
  379. ),
  380. SizedBox(width: 15,),
  381. ],
  382. ),
  383. Row(
  384. children: <Widget>[
  385. Expanded(
  386. child: Image.asset(
  387. R.assetsImagesImgTranslationIcon,
  388. width: 195,
  389. height: 175,
  390. ),
  391. flex: 4,
  392. ),
  393. Expanded(
  394. child: Column(
  395. children: <Widget>[
  396. Text(
  397. I18n.of(context).translation_butler_scenes,
  398. textScaleFactor: 1.0,
  399. textAlign: TextAlign.left,
  400. style: TextStyle(
  401. color: AppColors.NewAppbarTextColor,
  402. fontWeight: FontWeight.w700,
  403. fontSize: 15),
  404. ),
  405. SizedBox(height: 10,),
  406. _scenesPopMenu(),
  407. ],
  408. ),
  409. flex: 6,
  410. )
  411. ],
  412. ),
  413. Stack(children: <Widget>[
  414. Container(
  415. alignment: Alignment.topLeft,
  416. height: 110.5,
  417. padding: EdgeInsets.only(bottom: 10),
  418. decoration: BoxDecoration(
  419. color: Color(0xFFE9EEF4),
  420. borderRadius: BorderRadius.all(Radius.circular(10))),
  421. child: TextField(
  422. keyboardAppearance: Brightness.light,
  423. maxLines: 10,
  424. focusNode: focusNode,
  425. textInputAction: TextInputAction.done,
  426. onSubmitted: (input) {
  427. focusNode.unfocus();
  428. },
  429. decoration: new InputDecoration(
  430. hintText: I18n.of(context).translation_more_desc,
  431. hintStyle: TextStyle(fontSize: 14),
  432. border: InputBorder.none,
  433. ),
  434. // maxLines: 1,
  435. inputFormatters: [LengthLimitingTextInputFormatter(80)],
  436. // obscureText: true,
  437. style: TextStyle(textBaseline: TextBaseline.alphabetic),
  438. onChanged: (str) {
  439. if (_scrollController != null) {
  440. ///解决键盘遮挡输入框
  441. _scrollController.position.moveTo(
  442. 200,
  443. duration: Duration(milliseconds: 100),
  444. curve: Curves.easeIn,
  445. );
  446. }
  447. extraMsg = str;
  448. textLimitTips = I18n.of(context).translation_input_limit.replaceAll('/s1', (80-str.length).toString());
  449. setState(() {});
  450. },
  451. ),
  452. ),
  453. Positioned.fill(child: Container(padding: EdgeInsets.only(bottom: 5,right: 5),alignment: Alignment.bottomRight,child: Text(
  454. textLimitTips,
  455. textScaleFactor: 1.0,
  456. style: TextStyle(color: Color(0xFF95A3B2), fontSize: 11),
  457. ),)),
  458. ],),
  459. Padding(padding: EdgeInsets.only(left: 5,right: 5,top: 5,bottom: 8),child: Text(
  460. I18n.of(context).translation_butler_scenes_tips,
  461. textScaleFactor: 1.0,
  462. style: TextStyle(color: Color(0xFFFA7B3D), fontSize: 12),
  463. ),),
  464. ],
  465. ),
  466. ),
  467. ),
  468. ),
  469. Container(
  470. margin: EdgeInsets.only(left: 70, right: 70, top: 50),
  471. height: 47,
  472. child: RaisedButton(
  473. color: Color(0xff3875E9),
  474. shape: RoundedRectangleBorder(
  475. borderRadius: BorderRadius.all(Radius.circular(10))),
  476. child: Text(
  477. I18n.of(context).translation_butler_call + ' (50h)',
  478. textScaleFactor: 1.0,
  479. style: TextStyle(color: Colors.white, fontSize: 19),
  480. ),
  481. onPressed: () {
  482. timeStamp = DateTime.now().millisecondsSinceEpoch;
  483. apply();
  484. }),
  485. ),
  486. Container(
  487. width: double.maxFinite,
  488. alignment: Alignment.center,
  489. padding: EdgeInsets.only(left: 10, right: 10, top: 15,bottom: 20),
  490. child: Text(
  491. I18n.of(context).translation_butler_rules,
  492. textScaleFactor: 1.0,
  493. style: TextStyle(color: Color(0xffABABAB), fontSize: 13),
  494. ),
  495. ),
  496. ],
  497. );
  498. }
  499. Widget waitPage() {
  500. // ~/ 取整操作
  501. int seconds = secondsPassed % 60;
  502. int minutes = secondsPassed ~/ 60;
  503. return ListView(
  504. children: <Widget>[
  505. ///当前排队人数过多。。。
  506. Container(
  507. margin: EdgeInsets.all(10),
  508. child: Card(
  509. elevation: 2, // 阴影
  510. shape: RoundedRectangleBorder(
  511. borderRadius: BorderRadius.circular(10),
  512. // side: BorderSide(color: Colors.green,width: 25),
  513. ),
  514. child: Container(
  515. // width: double.maxFinite,
  516. // color: Colors.blue,
  517. padding: EdgeInsets.fromLTRB(14, 14, 14, 22),
  518. child: Column(
  519. children: <Widget>[
  520. Padding(
  521. padding: EdgeInsets.only(bottom: 20, top: 10),
  522. child: Text(
  523. I18n.of(context).translation_butler_tips2,
  524. textScaleFactor: 1.0,
  525. textAlign: TextAlign.left,
  526. style: TextStyle(color: Color(0xff797979), fontSize: 13),
  527. ),
  528. ),
  529. Container(
  530. width: double.maxFinite,
  531. child: Row(
  532. mainAxisSize: MainAxisSize.max,
  533. mainAxisAlignment: MainAxisAlignment.spaceAround,
  534. children: <Widget>[
  535. Column(
  536. mainAxisAlignment: MainAxisAlignment.center,
  537. children: <Widget>[
  538. fixedText(
  539. I18n.of(context).translation_butler_wait_people,
  540. fontSize: 16,
  541. color: Colors.black),
  542. SizedBox(
  543. height: 10,
  544. ),
  545. RichText(
  546. maxLines: 3,
  547. textAlign: TextAlign.center,
  548. text: TextSpan(children: [
  549. TextSpan(
  550. text: '$waitNum',
  551. style: TextStyle(
  552. color: Color(0xffFF1010),
  553. fontSize: 27)),
  554. TextSpan(
  555. text: ' ' +
  556. I18n.of(context)
  557. .translation_butler_wait_people_unit,
  558. style: TextStyle(
  559. color: Colors.black, fontSize: 17)),
  560. ]))
  561. ],
  562. ),
  563. Container(
  564. width: 1,
  565. height: 65,
  566. color: Color(0xffD8D8D8),
  567. ),
  568. Column(
  569. mainAxisAlignment: MainAxisAlignment.center,
  570. children: <Widget>[
  571. fixedText(
  572. I18n.of(context).translation_butler_wait_time,
  573. fontSize: 16,
  574. color: Colors.black),
  575. SizedBox(
  576. height: 10,
  577. ),
  578. RichText(
  579. maxLines: 3,
  580. textAlign: TextAlign.center,
  581. text: TextSpan(children: [
  582. TextSpan(
  583. text: '${waitNum*5}',
  584. style: TextStyle(
  585. color: Color(0xff3875E9),
  586. fontSize: 27)),
  587. TextSpan(
  588. text: ' ' + I18n.of(context).minute,
  589. style: TextStyle(
  590. color: Colors.black, fontSize: 17)),
  591. ]))
  592. ],
  593. ),
  594. ],
  595. ),
  596. )
  597. ],
  598. ),
  599. ),
  600. ),
  601. ),
  602. Padding(
  603. padding: EdgeInsets.only(left: 20, right: 10, top: 5, bottom: 10),
  604. child: Text(
  605. I18n.of(context).translation_butler_tips3,
  606. textScaleFactor: 1.0,
  607. style: TextStyle(color: Colors.black, fontSize: 18),
  608. ),
  609. ),
  610. Stack(
  611. alignment: Alignment.center,
  612. children: <Widget>[
  613. UnconstrainedBox(
  614. child: Container(
  615. //限制进度条的高度
  616. height: 190.0,
  617. //限制进度条的宽度
  618. width: 190.0,
  619. child: CircularProgressIndicator(
  620. //0~1的浮点数,用来表示进度多少;如果 value 为 null 或空,则显示一个动画,否则显示一个定值
  621. value: time60/60,
  622. strokeWidth: 5,
  623. //背景颜色
  624. backgroundColor: Color(0xffB2B2B2),
  625. //进度颜色
  626. valueColor:
  627. AlwaysStoppedAnimation<Color>(Color(0xff3875E9))),
  628. ),
  629. ),
  630. Column(
  631. children: <Widget>[
  632. Text(
  633. I18n.of(context).translation_butler_already_wait,
  634. textScaleFactor: 1.0,
  635. style: TextStyle(color: Colors.black, fontSize: 19),
  636. ),
  637. SizedBox(
  638. height: 10,
  639. ),
  640. Text(
  641. getFull(minutes) + ' : ' + getFull(seconds),
  642. textScaleFactor: 1.0,
  643. style: TextStyle(color: Color(0xffFF1010), fontSize: 35),
  644. )
  645. ],
  646. )
  647. ],
  648. ),
  649. Container(
  650. margin: EdgeInsets.only(left: 70, right: 70, top: 50),
  651. height: 47,
  652. child: RaisedButton(
  653. color: Color(0xff3875E9),
  654. shape: RoundedRectangleBorder(
  655. borderRadius: BorderRadius.all(Radius.circular(10))),
  656. child: Text(
  657. I18n.of(context).translation_butler_cancel,
  658. textScaleFactor: 1.0,
  659. style: TextStyle(color: Colors.white, fontSize: 19),
  660. ),
  661. onPressed: cancelOrder ),
  662. ),
  663. ],
  664. );
  665. }
  666. void cancelOrder()async {
  667. await SPUtils.save(Constants.TranslationHelper, null);
  668. setState(() {
  669. TranslateHKMgr().orderStatus = TranslateHKMgr.ORDER_STATUS_EMPTY;
  670. refreshOrder(null);
  671. MsgHandler.sendCancelTranslateOrder();
  672. });
  673. }
  674. void handleTick() {
  675. setState(() {
  676. secondsPassed = secondsPassed + 1; //需要更新UI
  677. time60=time60+1;
  678. if(time60==60){
  679. time60=0;
  680. }
  681. });
  682. }
  683. getFull(int sec) {
  684. return sec < 10 ? '0$sec' : '$sec';
  685. }
  686. }