video_upload.dart 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'dart:io';
  4. import 'dart:math';
  5. import 'package:chewie/chewie.dart';
  6. import 'package:flustars/flustars.dart' as FlutterStars;
  7. import 'package:flutter/material.dart';
  8. import 'package:flutter/services.dart';
  9. import 'package:flutter_screenutil/flutter_screenutil.dart';
  10. import 'package:flutter_spinkit/flutter_spinkit.dart';
  11. import 'package:image_picker/image_picker.dart';
  12. import 'package:liftmanager/common/common.dart';
  13. import 'package:liftmanager/internal/bbs/model/video_detail.dart';
  14. import 'package:liftmanager/internal/bbs/page/brand_page.dart';
  15. import 'package:liftmanager/net/api_service.dart';
  16. import 'package:liftmanager/res/resources.dart';
  17. import 'package:liftmanager/utils/fast_notification.dart';
  18. import 'package:liftmanager/utils/log_util.dart';
  19. import 'package:liftmanager/utils/oss_upload.dart';
  20. import 'package:liftmanager/utils/theme_utils.dart';
  21. import 'package:liftmanager/utils/toast.dart';
  22. import 'package:liftmanager/utils/utils.dart';
  23. import 'package:liftmanager/widgets/app_bar.dart';
  24. import 'package:liftmanager/widgets/selected_video_change.dart';
  25. import 'package:umeng_common_sdk/umeng_common_sdk.dart';
  26. import 'package:video_player/video_player.dart';
  27. class VideoUpload extends StatefulWidget {
  28. VideoUpload(this.id);
  29. final String id;
  30. @override
  31. State<StatefulWidget> createState() {
  32. return VideoUploadState();
  33. }
  34. }
  35. class VideoUploadState extends State<VideoUpload> {
  36. String brandName = "品牌";
  37. int brandIdss;
  38. String selectedBrandName = '';
  39. bool showBrandSelectionPanel = false;
  40. VideoDetailModel detailObj;
  41. VideoPlayerController _controller;
  42. VideoPlayerController _controllerFile;
  43. ChewieController _chewieController;
  44. String videoUrl;
  45. String str;
  46. String imagesUrl;
  47. double percent = 0.0;
  48. // 焦点控制
  49. FocusNode _focusNode1 = new FocusNode();
  50. GlobalKey _formKey = new GlobalKey<FormState>();
  51. TextEditingController _titleController = new TextEditingController();
  52. TextEditingController _descController = new TextEditingController();
  53. @override
  54. void initState() {
  55. UmengCommonSdk.onPageStart("视频上传");
  56. super.initState();
  57. print(widget.id);
  58. if (widget.id != null && widget.id != "") {
  59. NewApiService().getVideoDetail(int.parse(widget.id), 1, onSuccess: (res) {
  60. if (res != null) {
  61. detailObj = res;
  62. LogUtil.d(jsonEncode(res));
  63. setState(() {
  64. videoUrl = null;
  65. videoUrl = res.url;
  66. _titleController.text = res.title;
  67. _descController.text = res.descr;
  68. brandIdss = res.brandId;
  69. selectedBrandName = res.brandName;
  70. });
  71. }
  72. }, onError: (code, msg) {
  73. toasts(msg);
  74. });
  75. }
  76. }
  77. upLoadFileOnce(path) {
  78. showLoading(context, "正在上传...");
  79. NewApiService().upload(path, onSuccess: (res) {
  80. // imagesUrl.add(res.path);
  81. dismissLoading(context);
  82. setState(() {
  83. // videoUrl = [];
  84. // imagesUrl = [];
  85. // videoUrl.add(res.pathUrl);
  86. // imagesUrl.add(res.coverUrl);
  87. });
  88. }, onError: (code, msg) {
  89. dismissLoading(context);
  90. toasts(msg);
  91. });
  92. }
  93. randomInt(int min, int max) {
  94. return new Random().nextInt(max) % (max - min + 1) + min;
  95. }
  96. List<dynamic> brandList;
  97. Future getBrandList() async {
  98. await NewApiService().getBrandListType(null, onSuccess: (res) {
  99. if (res != null) {
  100. brandList = res;
  101. setState(() {});
  102. }
  103. }, onError: (code, msg) {
  104. toasts(msg);
  105. });
  106. }
  107. ///选择视频
  108. void selectPicker() {
  109. showDialog(
  110. context: context,
  111. builder: (BuildContext context) {
  112. return SimpleDialog(
  113. title: Text("选择方式"),
  114. children: ["拍照", '从手机相册选择'].map((String value) {
  115. print("$value");
  116. return SimpleDialogOption(
  117. child: Text(
  118. "${value}",
  119. style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
  120. ),
  121. onPressed: () {
  122. _getImage(value == '拍照' ? 1 : 0);
  123. Navigator.of(context).pop();
  124. },
  125. );
  126. }).toList());
  127. });
  128. }
  129. void _getImage(int key) async {
  130. print(key);
  131. try {
  132. await ImagePicker.pickVideo(
  133. source: key == 1 ? ImageSource.camera : ImageSource.gallery,
  134. ).then((File f) async {
  135. if (f != null) {
  136. _controllerFile = VideoPlayerController.file(f);
  137. _controllerFile.initialize().then((val) {
  138. _controllerFile.setLooping(true);
  139. int seconds = _controllerFile.value.duration.inSeconds;
  140. print("视频时长:$seconds");
  141. int fileSize = f.lengthSync(); //单位B
  142. print("视频大小:${fileSize}");
  143. print("视频大小:${f.path}");
  144. if (seconds <= 300) {
  145. _uploadImage(f.path);
  146. // upLoadFileOnce(_imageFile.path);
  147. // setState(() {});
  148. } else {
  149. toasts("视频时长不能大于5分钟!");
  150. }
  151. }).catchError((error) {
  152. print(error);
  153. print("error");
  154. toasts("上传失败,不支持此格式");
  155. });
  156. }
  157. });
  158. } catch (e) {
  159. toasts("没有权限,无法打开相册!");
  160. }
  161. }
  162. void _uploadImage(filePath) async {
  163. showPercent(context, () {
  164. dismissLoading(context);
  165. toasts("上传失败");
  166. }, () {
  167. if (videoUrl == null && str != null) {
  168. setState(() {
  169. videoUrl = str;
  170. settingVideoVC();
  171. print("videoUrl:" + videoUrl);
  172. dismissLoading(context);
  173. toasts("上传成功");
  174. });
  175. }
  176. });
  177. String uploadName = OssUtil.instance.getImageUploadName(filePath);
  178. await NewApiService.uploadImage(context, uploadName, filePath).then((data) {
  179. if (data.statusCode == 200) {
  180. str = NewApiUrl.URL_UPLOAD_IMAGE_OSS + "/" + uploadName;
  181. print("str:" + str);
  182. print(videoUrl);
  183. if (str != null) {
  184. Map obj = {"uploadName": uploadName, "success": true};
  185. FastNotification.push("percent", obj);
  186. }
  187. } else {
  188. Map obj = {"uploadName": uploadName, "success": false};
  189. FastNotification.push("percent", obj);
  190. }
  191. }).catchError((data) {
  192. Map obj = {"uploadName": uploadName, "success": false};
  193. FastNotification.push("percent", obj);
  194. });
  195. }
  196. FocusNode focusNode1 = new FocusNode();
  197. settingVideoVC() {
  198. _controller?.pause();
  199. _controller?.dispose();
  200. _chewieController?.dispose();
  201. _controller = VideoPlayerController.network(Utils.getImagePath(videoUrl));
  202. _chewieController = ChewieController(
  203. videoPlayerController: _controller,
  204. aspectRatio: 3 / 2,
  205. allowFullScreen: false,
  206. isLive: true,
  207. autoPlay: false,
  208. looping: true,
  209. // startAt: Duration(seconds: 1,minutes: 1),
  210. showControls: true,
  211. deviceOrientationsAfterFullScreen: [DeviceOrientation.portraitUp],
  212. // 是否在 UI 构建的时候就加载视频
  213. autoInitialize: true,
  214. // 拖动条样式颜色
  215. materialProgressColors: new ChewieProgressColors(
  216. playedColor: Colors.red,
  217. handleColor: Colors.blue,
  218. backgroundColor: Colors.grey,
  219. bufferedColor: Colors.lightGreen,
  220. ),
  221. );
  222. }
  223. @override
  224. void dispose() {
  225. UmengCommonSdk.onPageEnd("视频上传");
  226. _controller?.pause();
  227. _controller?.dispose();
  228. _chewieController?.dispose();
  229. // TODO: implement dispose
  230. super.dispose();
  231. }
  232. @override
  233. Widget build(BuildContext context) {
  234. double width = MediaQuery.of(context).size.width;
  235. double height = MediaQuery.of(context).size.height;
  236. // 监听FocusNode
  237. _focusNode1.addListener(() {
  238. // _focusNode1.hasFocus 是否聚焦
  239. print(_focusNode1.hasFocus);
  240. });
  241. return Scaffold(
  242. resizeToAvoidBottomPadding: false, //不让键盘弹上去
  243. appBar: MyAppBar(
  244. centerTitle: "上传视频",
  245. ),
  246. body: GestureDetector(
  247. onTap: () {
  248. // 点击空白页面关闭键盘
  249. FocusScope.of(context).requestFocus(focusNode1);
  250. },
  251. child: Stack(
  252. children: <Widget>[
  253. Container(
  254. child: ListView(children: <Widget>[
  255. Form(
  256. key: _formKey, //设置globalKey,用于后面获取FormState
  257. child: Column(
  258. children: <Widget>[
  259. ChioseThisRight(
  260. label: "电梯品牌",
  261. value: selectedBrandName,
  262. fun: () {
  263. setState(() {
  264. showBrandSelectionPanel = true;
  265. });
  266. getBrandList();
  267. }),
  268. Row(
  269. crossAxisAlignment: CrossAxisAlignment.start,
  270. mainAxisAlignment: MainAxisAlignment.start,
  271. children: <Widget>[
  272. Container(
  273. margin:
  274. EdgeInsets.only(top: ScreenUtil().setWidth(13)),
  275. height: 13,
  276. width: 2,
  277. color: Color(0xff5589FF),
  278. ),
  279. Container(
  280. padding: EdgeInsets.only(
  281. left: ScreenUtil().setWidth(13),
  282. top: ScreenUtil().setWidth(10),
  283. bottom: ScreenUtil().setWidth(5)),
  284. child: Text(
  285. "视频标题",
  286. style: TextStyle(
  287. color: Color(0xff222222),
  288. // fontSize:ScreenUtil().setSp(14),
  289. ),
  290. textAlign: TextAlign.left,
  291. ),
  292. ),
  293. ],
  294. ),
  295. Container(
  296. height: 80,
  297. padding: EdgeInsets.only(
  298. left: ScreenUtil().setWidth(15),
  299. right: ScreenUtil().setWidth(15),
  300. bottom: ScreenUtil().setWidth(20)),
  301. child: TextFormField(
  302. // autofocus: true,
  303. maxLength: 50,
  304. cursorColor: Color(0xffcccccc),
  305. controller: _titleController,
  306. maxLines: 5,
  307. decoration: InputDecoration(
  308. contentPadding: EdgeInsets.all(0),
  309. hintText: '请输入你上传视频的标题',
  310. hintStyle: TextStyle(color: Color(0xffcccccc)),
  311. focusedBorder: InputBorder.none,
  312. border: InputBorder.none,
  313. // filled: true, // 背景色
  314. // fillColor: Colors.cyan.withAlpha(35),
  315. // icon: Icon(Icons.person)
  316. ),
  317. // 校验
  318. validator: (val) {
  319. return val.trim().length > 0 ? null : "不能为空";
  320. }),
  321. ),
  322. Divider(),
  323. Row(
  324. crossAxisAlignment: CrossAxisAlignment.start,
  325. mainAxisAlignment: MainAxisAlignment.start,
  326. children: <Widget>[
  327. Container(
  328. margin:
  329. EdgeInsets.only(top: ScreenUtil().setWidth(13)),
  330. height: 13,
  331. width: 2,
  332. color: Color(0xff5589FF),
  333. ),
  334. Container(
  335. padding: EdgeInsets.only(
  336. left: ScreenUtil().setWidth(13),
  337. top: ScreenUtil().setWidth(10),
  338. bottom: ScreenUtil().setWidth(5)),
  339. child: Text(
  340. "视频简介",
  341. style: TextStyle(
  342. color: Color(0xff222222),
  343. // fontSize:ScreenUtil().setSp(14),
  344. ),
  345. textAlign: TextAlign.left,
  346. ),
  347. ),
  348. ],
  349. ),
  350. Container(
  351. height: 120,
  352. padding: EdgeInsets.only(
  353. left: ScreenUtil().setWidth(15),
  354. right: ScreenUtil().setWidth(15),
  355. bottom: ScreenUtil().setWidth(20)),
  356. child: TextFormField(
  357. // autofocus: true,
  358. maxLength: 500,
  359. cursorColor: Color(0xffcccccc),
  360. controller: _descController,
  361. maxLines: 5,
  362. decoration: InputDecoration(
  363. contentPadding: EdgeInsets.all(0),
  364. hintText: '请输入您上传视频的简介',
  365. hintStyle: TextStyle(color: Color(0xffcccccc)),
  366. focusedBorder: InputBorder.none,
  367. border: InputBorder.none,
  368. // filled: true, // 背景色
  369. // fillColor: Colors.cyan.withAlpha(35),
  370. // icon: Icon(Icons.person)
  371. ),
  372. // 校验
  373. validator: (val) {
  374. return val.trim().length > 0 ? null : "不能为空";
  375. }),
  376. ),
  377. Divider(),
  378. SizedBox(
  379. height: 20,
  380. ),
  381. Container(
  382. color: ThemeUtils.getTabsBg(context),
  383. padding: EdgeInsets.symmetric(horizontal: 10),
  384. child: Row(
  385. crossAxisAlignment: CrossAxisAlignment.end,
  386. children: [
  387. Stack(
  388. children: <Widget>[
  389. Container(
  390. height: 150,
  391. width: 150,
  392. child: SelectedVideo(
  393. image: videoUrl,
  394. videoPlay: videoPlay(),
  395. onTap: () {
  396. if (videoUrl == null) {
  397. selectPicker();
  398. }
  399. },
  400. ),
  401. ),
  402. (videoUrl != null)
  403. ? Positioned(
  404. top: 0,
  405. right: 0,
  406. child: GestureDetector(
  407. onTap: () {
  408. // print(index);
  409. // imagesUrl = null;
  410. setState(() {
  411. videoUrl = null;
  412. str = null;
  413. _controller.pause();
  414. // player.reset();
  415. });
  416. },
  417. child: Icon(
  418. const IconData(0xe651,
  419. fontFamily: "Iconfont"),
  420. size: 24.0,
  421. color: Color(0xff999999),
  422. ),
  423. ))
  424. : Container()
  425. ],
  426. ),
  427. Container(
  428. padding: EdgeInsets.only(left: 10),
  429. child: Text(
  430. "(建议时长<3分钟,大小<50M)",
  431. style: TextStyle(
  432. fontSize: ScreenUtil().setSp(13),
  433. color: Color(0xffCCCCCC)),
  434. textAlign: TextAlign.left,
  435. ),
  436. ),
  437. ],
  438. )),
  439. SizedBox(
  440. height: ScreenUtil().setWidth(80),
  441. ),
  442. ],
  443. ),
  444. )
  445. ])),
  446. Positioned(
  447. bottom: 0,
  448. left: 0,
  449. child: Container(
  450. width: width,
  451. padding: EdgeInsets.only(
  452. top: ScreenUtil().setWidth(15),
  453. bottom: ScreenUtil().setWidth(15),
  454. left: ScreenUtil().setWidth(25),
  455. right: ScreenUtil().setWidth(25)),
  456. color: ThemeUtils.getDialogTextFieldColor(context),
  457. child: Container(
  458. height: ScreenUtil().setWidth(44),
  459. decoration: BoxDecoration(
  460. color: Colours.blue_app_main,
  461. borderRadius:
  462. BorderRadius.circular(ScreenUtil().setWidth(22)),
  463. // gradient: const LinearGradient(
  464. // colors: [Color(0xFF00D9FF), Color(0xFF0287FF)]),
  465. ),
  466. child: FlatButton(
  467. // padding: EdgeInsets.all(15.0),
  468. child: Text("确认上传"),
  469. textColor: Colors.white,
  470. onPressed: () {
  471. if (brandIdss == null) {
  472. toasts("请选择品牌");
  473. return;
  474. }
  475. if (videoUrl == null) {
  476. toasts("请上传视频");
  477. return;
  478. }
  479. // String videos = videoUrl.join(",");
  480. // String images = imagesUrl.join(",");
  481. if ((_formKey.currentState as FormState).validate()) {
  482. showLoading(context, "正在提交...");
  483. if (widget.id != null && widget.id != "") {
  484. dynamic objEdit = {
  485. "brandId": brandIdss,
  486. "title": _titleController.text,
  487. "descr": _descController.text,
  488. "url": videoUrl,
  489. // "cover": images,
  490. "checkFlag": 2,
  491. "statuz": 1,
  492. "platformFlag": 1,
  493. "userId": FlutterStars.SpUtil.getString(
  494. Constant.userId),
  495. "id": detailObj.id
  496. };
  497. NewApiService().editVideo(objEdit,
  498. onSuccess: (res) {
  499. dismissLoading(context);
  500. toasts("修改成功");
  501. String initThisMyVideo =
  502. randomInt(1111, 9999).toString() +
  503. DateTime.now()
  504. .millisecondsSinceEpoch
  505. .toString();
  506. FastNotification.push(
  507. "initMyVideo", initThisMyVideo);
  508. if (_controller != null) {
  509. _controller.pause();
  510. }
  511. Navigator.of(context)..pop()..pop();
  512. }, onError: (code, msg) {
  513. dismissLoading(context);
  514. toasts(msg);
  515. });
  516. } else {
  517. dynamic obj = {
  518. "brandId": brandIdss,
  519. "title": _titleController.text,
  520. "descr": _descController.text,
  521. "url": videoUrl,
  522. // "cover": images,
  523. "checkFlag": 2,
  524. "statuz": 1,
  525. "platformFlag": 1,
  526. "userId":
  527. FlutterStars.SpUtil.getString(Constant.userId)
  528. };
  529. NewApiService().addVideo(obj, onSuccess: (res) {
  530. dismissLoading(context);
  531. toasts("提交成功");
  532. String initThisMyVideo =
  533. randomInt(1111, 9999).toString() +
  534. DateTime.now()
  535. .millisecondsSinceEpoch
  536. .toString();
  537. FastNotification.push(
  538. "initMyVideo", initThisMyVideo);
  539. if (_controller != null) {
  540. _controller.pause();
  541. }
  542. Navigator.pop(context);
  543. }, onError: (code, msg) {
  544. dismissLoading(context);
  545. toasts(msg);
  546. });
  547. }
  548. }
  549. },
  550. ),
  551. ),
  552. )),
  553. if (showBrandSelectionPanel)
  554. Positioned(
  555. top: 0,
  556. left: 0,
  557. child: GestureDetector(
  558. onTap: () {
  559. setState(() {
  560. showBrandSelectionPanel = false;
  561. });
  562. },
  563. child: Container(
  564. width: width,
  565. height: height,
  566. color: Color.fromRGBO(0, 0, 0, 0.5),
  567. ),
  568. ),
  569. ),
  570. if (showBrandSelectionPanel)
  571. Positioned(
  572. top: 0,
  573. right: 0,
  574. child: Container(
  575. width: width * 0.8,
  576. height: height,
  577. color: Colors.white,
  578. child: brandList == null
  579. ? loadCircle()
  580. : BrandSelectionPanel(
  581. brandList: brandList,
  582. onTapBrand: (records) {
  583. setState(() {
  584. selectedBrandName = records.name;
  585. brandIdss = records.id;
  586. showBrandSelectionPanel = false;
  587. });
  588. },
  589. ),
  590. ),
  591. ),
  592. ],
  593. ),
  594. ),
  595. );
  596. }
  597. Widget loadCircle() {
  598. return Container(
  599. padding: EdgeInsets.only(top: 10, bottom: 10),
  600. color: ThemeUtils.getTabsBg(context),
  601. child: Center(
  602. child: SpinKitFadingCircle(
  603. color: Colors.blueAccent,
  604. size: 30.0,
  605. ),
  606. ),
  607. );
  608. }
  609. Widget videoPlay() {
  610. if (_controller == null) return Container();
  611. return Container(
  612. child: ClipRRect(
  613. borderRadius: BorderRadius.circular(5),
  614. child: new Chewie(controller: _chewieController),
  615. ));
  616. }
  617. }
  618. class ChioseThisRight extends StatelessWidget {
  619. ChioseThisRight({
  620. Key key,
  621. this.value,
  622. this.label,
  623. this.fun,
  624. this.labelText = '请选择',
  625. this.labelTextColor = const Color(0xffcccccc),
  626. }) : super(key: key);
  627. String value;
  628. String label;
  629. Function fun;
  630. String labelText;
  631. Color labelTextColor;
  632. @override
  633. Widget build(BuildContext context) {
  634. double width = MediaQuery.of(context).size.width;
  635. return InkWell(
  636. onTap: () {
  637. fun();
  638. },
  639. child: Container(
  640. padding: EdgeInsets.only(
  641. top: ScreenUtil().setWidth(15), bottom: ScreenUtil().setWidth(15)),
  642. margin: EdgeInsets.only(left: ScreenUtil().setWidth(15)),
  643. decoration: BoxDecoration(
  644. border: Border(
  645. bottom: BorderSide(width: 0.5, color: Colours.line),
  646. ),
  647. ),
  648. child: Row(
  649. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  650. children: <Widget>[
  651. Text(
  652. label,
  653. style: TextStyle(
  654. color: Color(0xff222222),
  655. // fontSize: ScreenUtil().setSp(14)
  656. ),
  657. textAlign: TextAlign.start,
  658. ),
  659. value.isEmpty
  660. ? Container(
  661. child: Row(children: <Widget>[
  662. Text(
  663. labelText,
  664. style: TextStyle(
  665. color: labelTextColor,
  666. // fontSize: ScreenUtil().setSp(14)
  667. ),
  668. textAlign: TextAlign.start,
  669. ),
  670. Container(
  671. padding: EdgeInsets.only(top: 3),
  672. child: Icon(
  673. Icons.keyboard_arrow_right,
  674. size: 20.0,
  675. color: labelTextColor,
  676. ),
  677. ),
  678. SizedBox(width: 10)
  679. ]),
  680. )
  681. : Container(
  682. padding:
  683. EdgeInsets.only(right: ScreenUtil().setWidth(15)),
  684. child: Row(children: <Widget>[
  685. Text(
  686. value,
  687. style: TextStyle(
  688. color: labelTextColor,
  689. fontSize: ScreenUtil().setSp(14)),
  690. textAlign: TextAlign.start,
  691. ),
  692. Container(
  693. padding: EdgeInsets.only(top: 3),
  694. child: Icon(
  695. Icons.keyboard_arrow_right,
  696. size: 20.0,
  697. color: labelTextColor,
  698. ),
  699. ),
  700. // SizedBox(width: 10)
  701. ]),
  702. ),
  703. ]),
  704. ),
  705. );
  706. }
  707. }