import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:image_picker/image_picker.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:zhiying_base_widget/pages/feedback_page/feedback_record_page.dart'; import 'package:zhiying_base_widget/pages/feedback_page/widgets/feedback_image.dart'; import 'package:zhiying_base_widget/pages/feedback_page/widgets/feedback_tab_widget.dart'; import 'package:zhiying_base_widget/widgets/others/action_selected_alert/action_selected_alert.dart'; import 'package:zhiying_comm/util/log/let_log.dart'; class FeedbackPage extends StatefulWidget { @override _FeedbackPageState createState() => _FeedbackPageState(); } class _FeedbackPageState extends State { List _images = List(); bool _submitable = false; TextEditingController _feedback = TextEditingController(); @override void dispose() { _feedback.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, appBar: _createNav(), body: GestureDetector( onTap: () { FocusScope.of(context).requestFocus(FocusNode()); }, child: SafeArea( child: Column( children: [ Expanded( child: SingleChildScrollView( child: Column( children: [ Container( width: double.infinity, margin: EdgeInsets.only( top: 10, bottom: 10, left: 12.5, right: 12.5), padding: EdgeInsets.all(12.5), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(7.5)), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ _createTitle(), _createUpload(), _createSubmit(), ], ), ) ], ), ), ), Center( child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { Navigator.push( context, CupertinoPageRoute( builder: (_) => FeedbackRecordPage(), ), ); }, child: Container( width: 120, height: 30, margin: EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(15)), child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Padding( padding: EdgeInsets.only(right: 6), child: Icon( Icons.list, size: 12, ), ), Text( '反馈记录', style: TextStyle(fontSize: 13, color: Color(0xff333333)), ) ], ), ), ), ), ], ), ), ), ); } // 导航栏 Widget _createNav() { return CupertinoNavigationBar( border: Border( bottom: BorderSide( width: 0.0, // One physical pixel. style: BorderStyle.none, ), ), backgroundColor: Colors.white, leading: Navigator.canPop(context) ? GestureDetector( child: Container( padding: EdgeInsets.zero, child: Icon( Icons.arrow_back_ios, size: 20, ), ), onTap: () { if (Navigator.canPop(context)) { Navigator.pop(context); } }, ) : Container(), middle: Text( '意见反馈', style: TextStyle( fontSize: 15, color: Color(0xff333333), ), ), ); } Widget _createTitle() { return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( '反馈描述', style: TextStyle( fontSize: 14, color: Color(0xff333333), fontWeight: FontWeight.bold, ), ), Padding( padding: EdgeInsets.only(top: 4, bottom: 4), child: Row( children: List.generate( 3, (index) => Expanded( child: Container( margin: EdgeInsets.only(left: 2, right: 2), height: 28, child: FeedbackTabWidget('功能异常')), )), ), ), Container( height: 118, margin: EdgeInsets.only(left: 2, right: 2, top: 4, bottom: 4), child: CupertinoTextField( controller: _feedback, textAlignVertical: TextAlignVertical.top, style: TextStyle(fontSize: 12, color: Color(0xff333333)), maxLines: null, placeholder: '请输入您的意见(最多100个字)', placeholderStyle: TextStyle( fontSize: 12, color: Color(0xff999999), ), decoration: BoxDecoration( color: Color(0xfff9f9f9), borderRadius: BorderRadius.circular(7.5)), onChanged: (value) { if (value == null || value == '') { _submitable = false; } else { _submitable = true; } setState(() {}); }, ), ), ], ); } Widget _createUpload() { List images = List(); _images.forEach((file) { images.add(Container( margin: EdgeInsets.only(top: 4, bottom: 4, right: 8), width: 80, height: 80, child: FeedbackImageWidget( file: file, onDelete: () { _images.remove(file); setState(() {}); }, ), )); }); if (images.length < 4) { images.add(GestureDetector( child: Container( margin: EdgeInsets.only(top: 4, bottom: 4), decoration: BoxDecoration( borderRadius: BorderRadius.circular(7.5), color: Color(0xfff9f9f9)), height: 80, width: 80, child: Icon( Icons.add, size: 60, color: Color(0xffd8d8d8), ), ), onTap: _onAddImage, )); } return Column( children: [ Row( children: [ Padding( padding: EdgeInsets.only(right: 10, top: 4, bottom: 4), child: Text( '上传图片', style: TextStyle( fontSize: 14, color: Color(0xff333333), fontWeight: FontWeight.bold, ), ), ), Text( '最多上传4张,大小不超过1M/张', style: TextStyle( fontSize: 12, color: Color(0xff999999), ), ), ], ), Row( children: images, ) ], ); } Widget _createSubmit() { return GestureDetector( onTap: () { if (!_submitable) { return; } Logger.debug('提交:${_feedback.text.toString()}'); }, child: Container( margin: EdgeInsets.only(top: 24, bottom: 4), height: 45, decoration: BoxDecoration( color: _submitable ? Colors.redAccent : Color(0xffffe1e1), borderRadius: BorderRadius.circular(7.5), ), child: Center( child: Text( '提交意见', style: TextStyle( fontSize: 14, color: Colors.white, ), ), ), ), ); } void _onAddImage() async { if (_images.length >= 4) { Fluttertoast.showToast(msg: '最多上传4张图片'); return; } var status = await Permission.photos.status; if (status != PermissionStatus.granted) { status = await Permission.photos.request(); } if (status == PermissionStatus.denied) { Fluttertoast.showToast(msg: '暂无权限,图片选择失败'); return null; } final picker = ImagePicker(); PickedFile file; int index = await showModalBottomSheet( context: context, builder: (context) { return ActionSelectedAlert( // title: '拍照/选择图片', actions: ['拍照', '从相册选择图片'], ); }, isScrollControlled: false, backgroundColor: Colors.transparent); if (index != null) { if (index == 0) { file = await picker.getImage(source: ImageSource.camera); } else { file = await picker.getImage(source: ImageSource.gallery); } if (file == null) return; setState(() { _images.add(File(file.path)); }); // File resultFile = await EncodeUtil.compressImage(file, 800); } } }