OpenRoom.dart 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_picker/flutter_picker.dart';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:file_picker/file_picker.dart';
  5. import '../styles/colors.dart';
  6. import 'dart:io';
  7. import 'dart:async';
  8. import 'dart:convert';
  9. import 'dart:ui';
  10. import '../styles/totast.dart';
  11. import '../pages/RoomInfo.dart';
  12. import 'package:flutter_redux/flutter_redux.dart';
  13. import '../redux/AppState.dart';
  14. import '../net/HttpManager.dart';
  15. import '../net/Result.dart';
  16. import 'package:dio/dio.dart';
  17. import '../model/GameInfo.dart';
  18. import '../model/HouseLevel.dart';
  19. import '../plugins/ScreenStramPlugin.dart';
  20. import '../widget/Dialog.dart';
  21. import '../widget/LinearButton.dart';
  22. class OpenRoom extends StatefulWidget {
  23. OpenRoom({Key key, this.roomFlag}) : super(key: key);
  24. final String roomFlag; // 用来储存传递过来的值
  25. @override
  26. OpenRoomState createState() => OpenRoomState();
  27. }
  28. class OpenRoomState extends State<OpenRoom> {
  29. TextStyle titleStyle = TextStyle(color: Colors.white, fontSize: 14);
  30. TextStyle valStyle =
  31. TextStyle(color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500);
  32. Map<String, dynamic> editRoomInfo = {
  33. 'gameId': 1,
  34. 'houseLevel': 1,
  35. 'maxNumber': 5,
  36. 'scoreType': 0
  37. };
  38. List<GameInfo> gameList = [];
  39. List<HouseLevel> levelList = [];
  40. Future<void> getFilePath() async {
  41. File file = await FilePicker.getFile(type: FileType.ANY);
  42. if (file == null) {
  43. return;
  44. }
  45. print(file.statSync());
  46. Toast.show(context, '加载中', -1, 'loading');
  47. Result res = await HttpManager.post('assets/uploadFile', data: {
  48. 'file': UploadFileInfo(file, file.path),
  49. });
  50. Toast.hide();
  51. if (res.success) {
  52. setState(() {
  53. editRoomInfo['video'] = res.data[0];
  54. });
  55. }
  56. }
  57. Future<void> showSysDialog(id) async {
  58. Toast.show(context, '加载中', -1, 'loading');
  59. Result res = await HttpManager.get('alertMessage/getOne', data: {'id': id});
  60. Toast.hide();
  61. if (res.success) {
  62. MyDialog.showDialog(context, res.data['remark']);
  63. }
  64. }
  65. Future<void> saveInfo() async {
  66. if (!StoreProvider.of<AppState>(context).state.userInfo.createFlag) {
  67. showSysDialog(1);
  68. return;
  69. }
  70. if (!editRoomInfo.containsKey('gameId')) {
  71. Toast.show(context, '请选择游戏', 1500, 'info');
  72. return;
  73. }
  74. if (editRoomInfo['houseName'] == null || editRoomInfo['houseName'] == '') {
  75. Toast.show(context, '请输入房间标题', 1500, 'info');
  76. return;
  77. }
  78. // if (!editRoomInfo.containsKey('houseLevel')) {
  79. // Toast.show(context, '请选择房间等级', 1500, 'info');
  80. // return;
  81. // }
  82. if (editRoomInfo['houseType'] == '1' &&
  83. (editRoomInfo['gameHouseId'] == null ||
  84. editRoomInfo['gameHouseId'] == '')) {
  85. Toast.show(context, '请录入游戏房间号', 1500, 'info');
  86. return;
  87. }
  88. if (editRoomInfo['houseType'] == '1' &&
  89. (editRoomInfo['gameHousePassword'] == null ||
  90. editRoomInfo['gameHousePassword'] == '')) {
  91. Toast.show(context, '请录入游戏房间密码', 1500, 'info');
  92. return;
  93. }
  94. if (StoreProvider.of<AppState>(context).state.userInfo.moneyCoin != null) {
  95. HouseLevel chooseLevelInfo = HouseLevel.empty();
  96. for (var item in levelList) {
  97. if (item.id.toString() == editRoomInfo['houseLevel'].toString()) {
  98. chooseLevelInfo = item;
  99. }
  100. }
  101. if (StoreProvider.of<AppState>(context).state.userInfo.moneyCoin <
  102. chooseLevelInfo.entryCoin) {
  103. return;
  104. }
  105. } else {
  106. return;
  107. }
  108. bool hasPermission = await ScreenStreamPlugin.checkPermission();
  109. if (!hasPermission) {
  110. showDialog(
  111. context: context,
  112. builder: (context) => AlertDialog(
  113. title: Text('需要悬浮窗权限'),
  114. contentTextStyle: TextStyle(color: Colors.black87),
  115. content: Text('请在点击确定后,勾选"允许显示在其他应用的上层"'),
  116. actions: <Widget>[
  117. FlatButton(
  118. child: Text('确定'),
  119. onPressed: () {
  120. Navigator.of(context).pop();
  121. ScreenStreamPlugin.requestPermission();
  122. },
  123. ),
  124. ],
  125. ),
  126. );
  127. return;
  128. }
  129. editRoomInfo['createUser'] =
  130. StoreProvider.of<AppState>(context).state.userInfo.id;
  131. editRoomInfo['userId'] =
  132. StoreProvider.of<AppState>(context).state.userInfo.id;
  133. Toast.show(context, '加载中', -1, 'loading');
  134. Result res = await HttpManager.post('houseInfo/save', data: editRoomInfo);
  135. Toast.hide();
  136. if (res.success) {
  137. // HttpManager.post('houseInfo/join', data: {
  138. // 'houseId': res.data,
  139. // 'userId': StoreProvider.of<AppState>(context).state.userInfo.id
  140. // });
  141. Toast.show(context, '创建成功', 1500, 'success');
  142. Future.delayed(Duration(milliseconds: 1500), () {
  143. Navigator.pushReplacement(
  144. context,
  145. CupertinoPageRoute(
  146. builder: (context) => RoomInfo(roomId: res.data.toString())));
  147. });
  148. } else {
  149. Toast.show(context, res.error, 1500, 'info');
  150. }
  151. }
  152. Future<void> getInfo() async {
  153. Toast.show(context, '加载中', -1, 'loading');
  154. Result res = await HttpManager.get('gameInfo/all');
  155. if (res.success) {
  156. List<GameInfo> _list = [];
  157. for (var item in res.data) {
  158. _list.add(GameInfo.fromJson(item));
  159. }
  160. setState(() {
  161. gameList = _list;
  162. if (res.data.length > 0) {
  163. editRoomInfo['gameId'] = res.data[0]['id'];
  164. editRoomInfo['houseName'] =
  165. StoreProvider.of<AppState>(context).state.userInfo.nickname +
  166. '的' +
  167. res.data[0]['shortName'] +
  168. '房间';
  169. editRoomInfo['houseAbstract'] = res.data[0]['profile'] ?? '';
  170. }
  171. });
  172. } else {}
  173. Result res2 = await HttpManager.get('houseLevel/all');
  174. Toast.hide();
  175. if (res2.success) {
  176. List<HouseLevel> _list = [];
  177. for (var item in res2.data) {
  178. _list.add(HouseLevel.fromJson(item));
  179. }
  180. setState(() {
  181. levelList = _list;
  182. if (levelList.isNotEmpty) {
  183. editRoomInfo['houseLevel'] = res2.data[0]['id'];
  184. }
  185. });
  186. } else {}
  187. }
  188. @override
  189. void initState() {
  190. super.initState();
  191. editRoomInfo['houseType'] = widget.roomFlag;
  192. Future.delayed(Duration.zero, () {
  193. getInfo();
  194. });
  195. }
  196. @override
  197. Widget build(BuildContext context) {
  198. GameInfo chooseGameInfo = GameInfo.empty();
  199. for (var item in gameList) {
  200. if (item.id.toString() == editRoomInfo['gameId'].toString()) {
  201. chooseGameInfo = item;
  202. }
  203. }
  204. HouseLevel chooseLevelInfo = HouseLevel.empty();
  205. for (var item in levelList) {
  206. if (item.id.toString() == editRoomInfo['houseLevel'].toString()) {
  207. chooseLevelInfo = item;
  208. }
  209. }
  210. return WillPopScope(
  211. child: Scaffold(
  212. appBar: AppBar(
  213. backgroundColor: PRIMARY_COLOR,
  214. title: Text('创建' + (widget.roomFlag == '0' ? '普通' : '官方') + '房间'),
  215. centerTitle: true,
  216. elevation: 0,
  217. // actions: <Widget>[
  218. // Container(
  219. // width: 60,
  220. // child: FlatButton(
  221. // highlightColor: PRIMARY_COLOR,
  222. // padding: EdgeInsets.only(right: 0),
  223. // child: Text('规则',
  224. // style: TextStyle(color: Colors.white, fontSize: 13)),
  225. // onPressed: () {},
  226. // ),
  227. // )
  228. // ],
  229. ),
  230. body: Container(
  231. color: BG_COLOR,
  232. width: double.infinity,
  233. height: double.infinity,
  234. child: SingleChildScrollView(
  235. child: Container(
  236. color: BG_COLOR,
  237. child: Column(
  238. children: <Widget>[
  239. ChooseContent(
  240. title: '选择游戏',
  241. val: chooseGameInfo.gameName,
  242. onTapHomeMenu: () {
  243. showPicker(context);
  244. },
  245. ),
  246. Container(
  247. width: double.infinity,
  248. color: BG_SUB_COLOR,
  249. height: 210,
  250. child: Column(
  251. mainAxisAlignment: MainAxisAlignment.center,
  252. children: <Widget>[
  253. FlatButton(
  254. padding: EdgeInsets.all(0),
  255. color: Color(0xFF464B6A),
  256. highlightColor: Color(0xFF333557),
  257. child: Container(
  258. height: 38,
  259. width: 160,
  260. decoration: BoxDecoration(
  261. gradient: LinearGradient(
  262. begin: Alignment.topRight,
  263. colors: [Colors.black12, Colors.black38],
  264. )),
  265. child: Row(
  266. mainAxisAlignment: MainAxisAlignment.center,
  267. children: <Widget>[
  268. Padding(
  269. padding: EdgeInsets.only(right: 8),
  270. child: Image.asset(
  271. 'images/icon_shipin.png',
  272. width: 20,
  273. )),
  274. Text('上传图片或视频', style: titleStyle)
  275. ],
  276. ),
  277. ),
  278. onPressed: () {
  279. getFilePath();
  280. },
  281. ),
  282. Padding(
  283. padding: EdgeInsets.only(top: 12),
  284. child: Text(
  285. editRoomInfo.containsKey('video')
  286. ? '已选择'
  287. : '不上传则自动使用官方默认视频',
  288. style: TextStyle(
  289. color: Color(0xFF9BA0AE), fontSize: 13),
  290. ),
  291. )
  292. ],
  293. ),
  294. ),
  295. //房间标题
  296. // Container(
  297. // height: 60,
  298. // color: BG_COLOR,
  299. // padding:
  300. // EdgeInsets.symmetric(horizontal: 15, vertical: 8),
  301. // child: TextField(
  302. // textAlign: TextAlign.end,
  303. // style: valStyle,
  304. // maxLength: 10,
  305. // decoration: InputDecoration(
  306. // hintText: '请输入房间标题',
  307. // hintStyle: TextStyle(
  308. // color: Color(0xFF727785), fontSize: 13),
  309. // prefixIcon: Padding(
  310. // padding: EdgeInsets.symmetric(vertical: 12),
  311. // child: Text('房间标题', style: titleStyle),
  312. // ),
  313. // border: InputBorder.none,
  314. // counterStyle: TextStyle(fontSize: 0)),
  315. // onChanged: (value) {
  316. // editRoomInfo['houseName'] = value;
  317. // },
  318. // ),
  319. // ),
  320. InputContent(
  321. title: '房间标题',
  322. value: editRoomInfo['houseName'],
  323. onTextChange: (value) {
  324. editRoomInfo['houseName'] = value;
  325. }),
  326. Container(
  327. margin: EdgeInsets.symmetric(horizontal: 15),
  328. height: 1,
  329. color: BG_SUB_COLOR,
  330. ),
  331. //房间简介
  332. InputContent(
  333. title: '房间简介',
  334. value: editRoomInfo['houseAbstract'],
  335. onTextChange: (value) {
  336. editRoomInfo['houseAbstract'] = value;
  337. }),
  338. // Container(
  339. // height: 60,
  340. // color: BG_COLOR,
  341. // padding:
  342. // EdgeInsets.symmetric(horizontal: 15, vertical: 8),
  343. // child: TextField(
  344. // textAlign: TextAlign.end,
  345. // style: valStyle,
  346. // maxLength: 15,
  347. // decoration: InputDecoration(
  348. // hintText: '请输入房间简介',
  349. // hintStyle: TextStyle(
  350. // color: Color(0xFF727785), fontSize: 13),
  351. // prefixIcon: Padding(
  352. // padding: EdgeInsets.symmetric(vertical: 12),
  353. // child: Text('房间简介', style: titleStyle),
  354. // ),
  355. // border: InputBorder.none,
  356. // counterStyle: TextStyle(fontSize: 0)),
  357. // onChanged: (value) {
  358. // editRoomInfo['houseAbstract'] = value;
  359. // },
  360. // ),
  361. // ),
  362. Container(
  363. margin: EdgeInsets.symmetric(horizontal: 15),
  364. height: 1,
  365. color: BG_SUB_COLOR,
  366. ),
  367. //房间等级
  368. // ChooseContent(
  369. // title: '房间等级',
  370. // chooseLevelInfo: chooseLevelInfo,
  371. // isLevel: true,
  372. // onTapHomeMenu: () {
  373. // showLevelPicker(context);
  374. // },
  375. // ),
  376. Container(
  377. margin: EdgeInsets.symmetric(horizontal: 15),
  378. height: 1,
  379. color: BG_SUB_COLOR,
  380. ),
  381. //房间人数
  382. ChooseContent(
  383. title: '房卡人数',
  384. val: editRoomInfo['maxNumber'].toString() + '人次房卡',
  385. icon: Image.asset('images/icon_yiwen.png'),
  386. onTapHomeMenu: () {
  387. showNumPicker(context);
  388. },
  389. ),
  390. Container(
  391. margin: EdgeInsets.symmetric(horizontal: 15),
  392. height: 1,
  393. color: BG_SUB_COLOR,
  394. ),
  395. //房间人数
  396. ChooseContent(
  397. title: '胜利条件',
  398. val: editRoomInfo['scoreType'] == 0 ? '评分' : '吃鸡',
  399. onTapHomeMenu: () {
  400. showScoreType(context);
  401. },
  402. ),
  403. _bottomWidget(),
  404. ],
  405. ),
  406. ),
  407. ),
  408. ),
  409. floatingActionButton: Padding(
  410. padding: EdgeInsets.fromLTRB(15, 39, 15, 10),
  411. child: LinearButton(
  412. onTapHomeMenu: () {
  413. saveInfo();
  414. },
  415. childWidget: Row(
  416. mainAxisAlignment: MainAxisAlignment.center,
  417. children: <Widget>[
  418. Padding(
  419. padding: EdgeInsets.only(right: 6),
  420. child: Image.asset('images/icon_renci.png'),
  421. ),
  422. Text(
  423. '×${editRoomInfo["maxNumber"]}' ,
  424. style: TextStyle(
  425. color: Colors.white,
  426. fontSize: 16,
  427. fontWeight: FontWeight.w500),
  428. ),
  429. Padding(
  430. padding: EdgeInsets.only(left: 20),
  431. child: Text(
  432. '创建房间',
  433. style: TextStyle(
  434. color: Colors.white,
  435. fontSize: 16,
  436. fontWeight: FontWeight.w500),
  437. ),
  438. )
  439. ],
  440. ),
  441. ),
  442. ),
  443. floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,),
  444. onWillPop: () {
  445. Toast.hide();
  446. Navigator.pop(context);
  447. return Future.value(false);
  448. },
  449. );
  450. }
  451. Widget _bottomWidget() {
  452. if (widget.roomFlag == '1')
  453. return Column(
  454. children: <Widget>[
  455. Container(
  456. height: 10,
  457. color: BG_SUB_COLOR,
  458. ),
  459. //游戏房间号
  460. Container(
  461. height: 60,
  462. color: BG_COLOR,
  463. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 8),
  464. child: TextField(
  465. textAlign: TextAlign.end,
  466. style: valStyle,
  467. maxLength: 15,
  468. decoration: InputDecoration(
  469. hintText: '请输入游戏房间号',
  470. hintStyle: TextStyle(color: Color(0xFF727785), fontSize: 13),
  471. prefixIcon: Padding(
  472. padding: EdgeInsets.symmetric(vertical: 12),
  473. child: Text('游戏房间号', style: titleStyle),
  474. ),
  475. border: InputBorder.none,
  476. counterStyle: TextStyle(fontSize: 0)),
  477. onChanged: (value) {
  478. editRoomInfo['gameHouseId'] = value;
  479. },
  480. ),
  481. ),
  482. Container(
  483. height: 1,
  484. color: BG_SUB_COLOR,
  485. ),
  486. //游戏中房间密��
  487. Container(
  488. height: 60,
  489. color: BG_COLOR,
  490. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 8),
  491. child: TextField(
  492. textAlign: TextAlign.end,
  493. style: valStyle,
  494. maxLength: 10,
  495. decoration: InputDecoration(
  496. hintText: '请输入密码',
  497. hintStyle: TextStyle(color: Color(0xFF727785), fontSize: 13),
  498. prefixIcon: Padding(
  499. padding: EdgeInsets.symmetric(vertical: 12),
  500. child: Text('游戏中房间密码', style: titleStyle),
  501. ),
  502. border: InputBorder.none,
  503. counterStyle: TextStyle(fontSize: 0)),
  504. onChanged: (value) {
  505. editRoomInfo['gameHousePassword'] = value;
  506. },
  507. ),
  508. ),
  509. ],
  510. );
  511. else {
  512. return Container();
  513. }
  514. }
  515. void showPicker(BuildContext context) {
  516. List<String> _list = [];
  517. for (var item in gameList) {
  518. _list.add(item.gameName);
  519. }
  520. String PickerData = json.encode(_list);
  521. Picker(
  522. confirmText: '确定',
  523. cancelText: '取消',
  524. adapter: PickerDataAdapter<String>(
  525. pickerdata: JsonDecoder().convert(PickerData)),
  526. changeToFirst: true,
  527. textAlign: TextAlign.left,
  528. columnPadding: const EdgeInsets.all(8.0),
  529. onConfirm: (Picker picker, List value) {
  530. setState(() {
  531. editRoomInfo['gameId'] = gameList[value[0]].id;
  532. editRoomInfo['houseName'] =
  533. StoreProvider.of<AppState>(context).state.userInfo.nickname +
  534. '的' +
  535. gameList[value[0]].shortName +
  536. '房间';
  537. editRoomInfo['houseAbstract'] = gameList[value[0]].profile ?? '';
  538. });
  539. }).showModal(this.context);
  540. }
  541. void showNumPicker(BuildContext context) {
  542. List _list = [];
  543. List _listName = [];
  544. List _member=[5,10,15,20,25,50,100];
  545. for (var item in _member) {
  546. _list.add(item);
  547. _listName.add(item.toString() + '人次房卡');
  548. }
  549. String pickerData = json.encode(_listName);
  550. Picker(
  551. confirmText: '确定',
  552. cancelText: '取消',
  553. adapter: PickerDataAdapter<String>(
  554. pickerdata: JsonDecoder().convert(pickerData)),
  555. changeToFirst: true,
  556. textAlign: TextAlign.left,
  557. columnPadding: const EdgeInsets.all(8.0),
  558. onConfirm: (Picker picker, List value) {
  559. setState(() {
  560. editRoomInfo['maxNumber'] = _list[value[0]];
  561. });
  562. }).showModal(this.context);
  563. }
  564. void showScoreType(BuildContext context) {
  565. List _list = ['评分', '吃鸡'];
  566. String PickerData = json.encode(_list);
  567. Picker(
  568. confirmText: '确定',
  569. cancelText: '取消',
  570. adapter: PickerDataAdapter<String>(
  571. pickerdata: JsonDecoder().convert(PickerData)),
  572. changeToFirst: true,
  573. textAlign: TextAlign.left,
  574. columnPadding: const EdgeInsets.all(8.0),
  575. onConfirm: (Picker picker, List value) {
  576. setState(() {
  577. editRoomInfo['scoreType'] = _list[value[0]] == '评分' ? 0 : 1;
  578. });
  579. }).showModal(this.context);
  580. }
  581. void showLevelPicker(BuildContext context) {
  582. List<String> _list = [];
  583. for (var item in levelList) {
  584. _list.add(item.levelName);
  585. }
  586. String PickerData = json.encode(_list);
  587. Picker(
  588. confirmText: '确定',
  589. cancelText: '取消',
  590. adapter: PickerDataAdapter<String>(
  591. pickerdata: JsonDecoder().convert(PickerData)),
  592. changeToFirst: true,
  593. textAlign: TextAlign.left,
  594. columnPadding: const EdgeInsets.all(8.0),
  595. onConfirm: (Picker picker, List value) {
  596. setState(() {
  597. editRoomInfo['houseLevel'] = levelList[value[0]].id;
  598. });
  599. }).showModal(this.context);
  600. }
  601. }
  602. typedef int OnTapHomeMenu();
  603. typedef ValueChanged<T> = void Function(T value);
  604. class ChooseContent extends StatelessWidget {
  605. ChooseContent(
  606. {Key key,
  607. this.title,
  608. this.val,
  609. this.chooseLevelInfo,
  610. this.isLevel = false,
  611. this.icon,
  612. this.onTapHomeMenu})
  613. : super(key: key);
  614. final String title;
  615. final String val;
  616. final OnTapHomeMenu onTapHomeMenu;
  617. final HouseLevel chooseLevelInfo;
  618. final Image icon;
  619. final bool isLevel;
  620. GlobalKey anchorKey = GlobalKey();
  621. @override
  622. Widget build(BuildContext context) {
  623. return Container(
  624. child: InkWell(
  625. child: Container(
  626. height: 60,
  627. padding: EdgeInsets.symmetric(horizontal: 15),
  628. child: Row(
  629. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  630. children: <Widget>[
  631. Text(title, style: TextStyle(fontSize: 14, color: Colors.white)),
  632. icon != null
  633. ? InkWell(
  634. onTap: () {
  635. //弹出
  636. RenderBox renderBox =
  637. anchorKey.currentContext.findRenderObject();
  638. var offset = renderBox.localToGlobal(Offset.zero);
  639. print(offset.dx.toString() + ',' + offset.dy.toString());
  640. Navigator.of(context).push(PageRouteBuilder(
  641. opaque: false,
  642. transitionDuration: Duration(milliseconds: 300),
  643. transitionsBuilder: (BuildContext context,
  644. Animation<double> animation,
  645. Animation<double> secondaryAnimation,
  646. Widget child) {
  647. return FadeTransition(
  648. opacity: CurvedAnimation(
  649. parent: animation, curve: Curves.linear),
  650. child: child,
  651. );
  652. },
  653. pageBuilder: (BuildContext context, _, __) {
  654. return FloatTextContent(
  655. dx: offset.dx, dy: offset.dy);
  656. }));
  657. },
  658. child: Padding(
  659. padding: EdgeInsets.all(9),
  660. child: icon,
  661. key: anchorKey))
  662. : Container(),
  663. Expanded(
  664. flex: 1,
  665. child: isLevel
  666. ? Row(
  667. mainAxisAlignment: MainAxisAlignment.end,
  668. children: <Widget>[
  669. chooseLevelInfo.icon != null
  670. ? Image.network(
  671. chooseLevelInfo.icon,
  672. width: 22,
  673. )
  674. : Container(),
  675. Text(
  676. chooseLevelInfo.levelName ?? '',
  677. style: TextStyle(color: Color(0xFFF9D881)),
  678. ),
  679. Padding(
  680. padding: EdgeInsets.only(left: 20, right: 2),
  681. child: Image.asset('images/icon_jinbi_da_bai.png',
  682. width: 20),
  683. ),
  684. Text(
  685. '×' + (chooseLevelInfo.entryCoin ?? 0).toString(),
  686. style: TextStyle(
  687. color: Colors.white,
  688. fontSize: 15,
  689. fontWeight: FontWeight.w500),
  690. )
  691. ],
  692. )
  693. : Text(val ?? '',
  694. style: TextStyle(
  695. fontSize: 15,
  696. color: Colors.white,
  697. fontWeight: FontWeight.w500),
  698. textAlign: TextAlign.right),
  699. ),
  700. Image.asset('images/icon_inter.png', width: 24)
  701. ],
  702. ),
  703. ),
  704. onTap: onTapHomeMenu,
  705. ));
  706. }
  707. }
  708. class InputContent extends StatefulWidget {
  709. InputContent({Key key, this.title, this.value, this.onTextChange})
  710. : super(key: key);
  711. final String title;
  712. final String value;
  713. final ValueChanged onTextChange;
  714. @override
  715. InputContentState createState() => InputContentState();
  716. }
  717. class InputContentState extends State<InputContent> {
  718. TextEditingController _controller;
  719. @override
  720. void initState() {
  721. super.initState();
  722. _controller = TextEditingController();
  723. }
  724. @override
  725. void didUpdateWidget(InputContent oldWidget) {
  726. super.didUpdateWidget(oldWidget);
  727. _controller.text = widget.value ?? '';
  728. }
  729. @override
  730. Widget build(BuildContext context) {
  731. return Container(
  732. height: 60,
  733. color: BG_COLOR,
  734. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 8),
  735. child: TextField(
  736. controller: _controller,
  737. textAlign: TextAlign.end,
  738. style: TextStyle(
  739. fontSize: 15, color: Colors.white, fontWeight: FontWeight.w500),
  740. maxLength: 10,
  741. decoration: InputDecoration(
  742. hintText: '请输入' + widget.title,
  743. hintStyle: TextStyle(color: Color(0xFF727785), fontSize: 13),
  744. prefixIcon: Padding(
  745. padding: EdgeInsets.symmetric(vertical: 12),
  746. child: Text(widget.title,
  747. style: TextStyle(fontSize: 14, color: Colors.white)),
  748. ),
  749. border: InputBorder.none,
  750. counterStyle: TextStyle(fontSize: 0)),
  751. onChanged: widget.onTextChange,
  752. ),
  753. );
  754. }
  755. }
  756. class FloatTextContent extends StatelessWidget {
  757. final num dx;
  758. final num dy;
  759. FloatTextContent({this.dx, this.dy});
  760. @override
  761. Widget build(BuildContext context) {
  762. return GestureDetector(
  763. onTap: () {
  764. Navigator.of(context).pop();
  765. },
  766. child: Container(
  767. color: Colors.transparent,
  768. child: Stack(
  769. children: <Widget>[
  770. Positioned(
  771. left: dx + 31,
  772. top: dy + 9,
  773. child: Container(
  774. padding: EdgeInsets.all(10),
  775. constraints: BoxConstraints(maxWidth: 241),
  776. color: Color(0xFF3A3E61),
  777. child: Text(
  778. '房主可以选择不同人次的房卡进行开始比赛,同步消耗自己相应的参赛名额,比如选择50人次房卡,系统从我的账号上扣除50人次参赛名额,房间内最多可进入50人参加比赛',
  779. style: TextStyle(
  780. color: Colors.white,
  781. fontSize: 12,
  782. fontWeight: FontWeight.w400,
  783. decoration: TextDecoration.none)),
  784. ),
  785. )
  786. ],
  787. ),
  788. ),
  789. );
  790. }
  791. }