add_news.dart 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import 'dart:io';
  2. import 'package:flutter/material.dart';
  3. import 'package:fun_selfie_app/widgets/common_form_item.dart';
  4. import 'package:image_picker/image_picker.dart';
  5. import 'package:dio/dio.dart';
  6. import 'package:fun_selfie_app/utils/common_toast.dart';
  7. import 'package:date_format/date_format.dart';
  8. import 'package:fun_selfie_app/utils/permission_request.dart';
  9. class AddNewsPage extends StatefulWidget {
  10. const AddNewsPage({Key? key}) : super(key: key);
  11. @override
  12. State<StatefulWidget> createState() => _AddNewsPageState();
  13. }
  14. class _AddNewsPageState extends State<AddNewsPage> {
  15. bool _switchVal = false;
  16. File? imagePath;
  17. GlobalKey<FormState> formKey = GlobalKey<FormState>(); //表单验证
  18. final TextEditingController newsName = TextEditingController();
  19. final TextEditingController newsPlace = TextEditingController();
  20. final TextEditingController newsDate = TextEditingController();
  21. final TextEditingController newsZs = TextEditingController();
  22. final TextEditingController newsDs = TextEditingController();
  23. final TextEditingController newsDsDate = TextEditingController();
  24. final ImagePicker _imagePicker = ImagePicker();
  25. @override
  26. Widget build(BuildContext context) {
  27. return Scaffold(
  28. appBar: AppBar(
  29. title: const Text('创建活动'),
  30. centerTitle: true,
  31. // titleSpacing: 40,
  32. actions: [
  33. Padding(
  34. padding: const EdgeInsets.only(right: 40),
  35. child: TextButton(
  36. child: const Text(
  37. '保存',
  38. style: TextStyle(color: Colors.white, fontSize: 20),
  39. ),
  40. onPressed: () {
  41. onSubmit();
  42. }),
  43. ),
  44. ],
  45. ),
  46. body: Form(
  47. key: formKey,
  48. autovalidateMode: AutovalidateMode.onUserInteraction,
  49. child: SingleChildScrollView(
  50. child: Column(children: <Widget>[
  51. CommonFormItem(
  52. label: '活动的名称',
  53. hitText: '请输入',
  54. controller: newsName,
  55. validator: (v) => (v == '') ? "请输入" : null,
  56. ),
  57. CommonFormItem(
  58. label: '活动的地点',
  59. hitText: '请输入',
  60. controller: newsPlace,
  61. validator: (v) => (v == '') ? "请输入" : null,
  62. ),
  63. CommonFormItem(
  64. readOnly: true,
  65. label: '开始日期',
  66. hitText: '请输入',
  67. controller: newsDate,
  68. validator: (v) => (v == '') ? "请输入" : null,
  69. onTap: () async {
  70. final curentDate = DateTime.now();
  71. showDatePicker(
  72. context: context,
  73. initialDate: curentDate,
  74. firstDate: curentDate,
  75. lastDate: DateTime(2100),
  76. locale: const Locale('zh'))
  77. .then((value) {
  78. if (value == null) return;
  79. var dateStr = formatDate(
  80. value.toLocal(), [yyyy, '年', mm, '月', dd, '日']);
  81. newsDate.text = dateStr;
  82. });
  83. },
  84. ),
  85. CommonFormItem(
  86. label: '连拍张数',
  87. hitText: '请输入',
  88. controller: newsZs,
  89. validator: (v) => (v == '') ? "请输入" : null,
  90. ),
  91. CommonFormItem(
  92. label: '自拍倒数',
  93. hitText: '请输入',
  94. suffixText: '秒',
  95. controller: newsDs,
  96. validator: (v) => (v == '') ? "请输入" : null,
  97. ),
  98. CommonFormItem(
  99. label: '首张补充倒数时间',
  100. hitText: '请输入',
  101. suffixText: '秒',
  102. controller: newsDsDate,
  103. validator: (v) => (v == '') ? "请输入" : null,
  104. ),
  105. Padding(
  106. padding: const EdgeInsets.only(left: 20, right: 20),
  107. child: Row(
  108. children: [
  109. const Text('平铺相纸', style: TextStyle(fontSize: 18)),
  110. const Expanded(child: SizedBox()),
  111. Transform.scale(
  112. scale: 1.7,
  113. child: Switch(
  114. value: _switchVal,
  115. inactiveTrackColor: Colors.grey,
  116. inactiveThumbColor: Colors.white,
  117. activeColor: const Color.fromARGB(100, 98, 0, 238),
  118. activeTrackColor:
  119. const Color.fromARGB(100, 98, 0, 238),
  120. onChanged: (value) {
  121. setState(() {
  122. _switchVal = !_switchVal;
  123. });
  124. }))
  125. ],
  126. ),
  127. ),
  128. Center(
  129. child: imagePath == null
  130. ? const Text('')
  131. : InkWell(
  132. child: Image.file(imagePath!),
  133. onTap: () {
  134. selectImage(context);
  135. }),
  136. ),
  137. _switchVal && imagePath == null
  138. ? FloatingActionButton.extended(
  139. label: const Text('选择边框'),
  140. onPressed: () {
  141. selectImage(context);
  142. },
  143. )
  144. : const Text('')
  145. ]))));
  146. }
  147. Future selectImage(BuildContext context) async {
  148. bool result = await permissionCheckAndRequest(context, "通知");
  149. if (result) debugPrint("已拥有该权限");
  150. XFile? image = await _imagePicker.pickImage(source: ImageSource.gallery);
  151. if (image == null) return;
  152. final File filePath = File(image.path);
  153. // upLoadImage(filePath);
  154. setState(() {
  155. imagePath = filePath;
  156. });
  157. }
  158. upLoadImage(File image) async {
  159. String path = image.path;
  160. var name = path.substring(path.lastIndexOf("/") + 1, path.length);
  161. var suffix = name.substring(name.lastIndexOf(".") + 1, name.length);
  162. FormData formData = FormData.fromMap({
  163. "userId": "10000024",
  164. "file": await MultipartFile.fromFile(
  165. path,
  166. filename: name,
  167. //contentType: ContentType.parse("image/$suffix")
  168. )
  169. });
  170. Dio dio = Dio();
  171. var respone = await dio.post<String>("/upload", data: formData);
  172. if (respone.statusCode == 200) {
  173. CommonToast.okToast('图片上传成功');
  174. }
  175. }
  176. onSubmit() {
  177. final form = formKey.currentState;
  178. if (form!.validate()) {
  179. if (_switchVal && imagePath == null) {
  180. CommonToast.okToast('请选择活动边框');
  181. return;
  182. }
  183. }
  184. }
  185. }