import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:async/async.dart'; import 'package:flutter/material.dart'; import 'package:flutter_osc/model/api.dart'; import 'package:flutter_osc/util/DataUtils.dart'; import 'package:http/http.dart' as http; import 'package:image_picker/image_picker.dart'; class PublishTweetPage extends StatefulWidget { @override State createState() { return PublishTweetPageState(); } } class PublishTweetPageState extends State { TextEditingController _controller = TextEditingController(); List fileList = []; Future? _imageFile; bool isLoading = false; String msg = ""; Widget getBody() { var textField = TextField( decoration: InputDecoration( hintText: "说点什么吧~", hintStyle: TextStyle(color: const Color(0xFF808080)), border: OutlineInputBorder( borderRadius: const BorderRadius.all(const Radius.circular(10.0)))), maxLines: 6, maxLength: 150, controller: _controller, ); var gridView = Builder( builder: (ctx) { return GridView.count( crossAxisCount: 4, children: List.generate(fileList.length + 1, (index) { var content; if (index == 0) { // 添加图片按钮 var addCell = Center( child: Image.asset( './images/ic_add_pics.png', width: 80.0, height: 80.0, )); content = GestureDetector( onTap: () { // 添加图片 pickImage(ctx); }, child: addCell, ); } else { // 被选中的图片 content = Center( child: Image.file( fileList[index - 1], width: 80.0, height: 80.0, fit: BoxFit.cover, )); } return Container( margin: const EdgeInsets.all(2.0), width: 80.0, height: 80.0, color: const Color(0xFFECECEC), child: content, ); }), ); }, ); var children = [ Text( "提示:由于OSC的openapi限制,发布动弹的接口只支持上传一张图片,本项目可添加最多9张图片,但OSC只会接收最后一张图片。", style: TextStyle(fontSize: 12.0), ), textField, Container( margin: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0), height: 200.0, child: gridView) ]; if (isLoading) { children.add(Container( margin: const EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 0.0), child: Center( child: CircularProgressIndicator(), ), )); } else { children.add(Container( margin: const EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 0.0), child: Center( child: Text(msg), ))); } return Container( padding: const EdgeInsets.all(5.0), child: Column( children: children, ), ); } // 相机拍照或者从图库选择图片 pickImage(ctx) { // 如果已添加了9张图片,则提示不允许添加更多 num size = fileList.length; if (size >= 9) { ScaffoldMessenger.of(ctx).showSnackBar(SnackBar( content: Text("最多只能添加9张图片!"), )); return; } showModalBottomSheet(context: context, builder: _bottomSheetBuilder); } Widget _bottomSheetBuilder(BuildContext context) { return Container( height: 182.0, child: Padding( padding: const EdgeInsets.fromLTRB(0.0, 30.0, 0.0, 30.0), child: Column( children: [ _renderBottomMenuItem("相机拍照", ImageSource.camera), Divider( height: 2.0, ), _renderBottomMenuItem("图库选择照片", ImageSource.gallery) ], ), )); } _renderBottomMenuItem(title, ImageSource source) { var item = Container( height: 60.0, child: Center(child: Text(title)), ); return InkWell( child: item, onTap: () { Navigator.of(context).pop(); setState(() { _imageFile = ImagePicker().pickImage(source: source); }); }, ); } sendTweet(ctx, token) async { if (token == null) { ScaffoldMessenger.of(ctx).showSnackBar(SnackBar( content: Text("未登录!"), )); return; } String content = _controller.text; if (content == null || content.length == 0 || content.trim().length == 0) { ScaffoldMessenger.of(ctx).showSnackBar(SnackBar( content: Text("请输入动弹内容!"), )); } try { Map params = Map(); params['msg'] = content; params['access_token'] = token; var request = http.MultipartRequest('POST', Uri.parse(Api.PUB_TWEET)); request.fields.addAll(params); if (fileList != null && fileList.length > 0) { for (File f in fileList) { var stream = http.ByteStream(DelegatingStream.typed(f.openRead())); var length = await f.length(); var filename = f.path.substring(f.path.lastIndexOf("/") + 1); request.files.add( http.MultipartFile('img', stream, length, filename: filename)); } } setState(() { isLoading = true; }); var response = await request.send(); response.stream.transform(utf8.decoder).listen((value) { print(value); if (value != null) { var obj = json.decode(value); var error = obj['error']; setState(() { if (error != null && error == '200') { // 成功 setState(() { isLoading = false; msg = "发布成功"; fileList.clear(); }); _controller.clear(); } else { setState(() { isLoading = false; msg = "发布失败:$error"; }); } }); } }); } catch (exception) { print(exception); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("发布动弹", style: TextStyle(color: Colors.white)), iconTheme: IconThemeData(color: Colors.white), actions: [ Builder( builder: (ctx) { return IconButton( icon: Icon(Icons.send), onPressed: () { // 发送动弹 DataUtils.isLogin().then((isLogin) { if (isLogin) { return DataUtils.getAccessToken(); } else { return null; } }).then((token) { sendTweet(ctx, token); }); }); }, ) ], ), body: FutureBuilder( future: _imageFile, builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done && snapshot.data != null && _imageFile != null) { fileList.add(File(snapshot.data!.path)); _imageFile = null; } return getBody(); }, ), ); } }