Flutter项目问题(上传图片、时间格式、将组件生成图片并保存)

1.Flutter项目上传图片(例如更改头像)

1)安装依赖包

这个依赖包可以在官网上获取:地址

  image_picker: ^0.6.7+17

2)引入文件

import 'package:image_picker/image_picker.dart';
import 'dart:io';

3)选取图片【在需要上传图片的点击事件中使用这个方法】

File _image;
final picker = ImagePicker();
Future getImage() async {
    var pickedFile = await picker.getImage(source: ImageSource.gallery);
    setState(() {
      _image = File(pickedFile.path);
      if (pickedFile != null) {
       //在这里可以写后端给的接口进行图片上传
      }
      else {
        print('No image selected.');
      }
    });
  }

小提示:将图片文件数据发送到后端的时候需要注意后端接收的是什么类型的数据
如果是文件MultipartFile类型的那么可以这样写:

upLoadImage(File image) async {
    String path = image.path;
    var name = path.substring(path.lastIndexOf("/") + 1, path.length);
    FormData formData =FormData.fromMap({
      "file": await MultipartFile.fromFile(path, filename: name)
    });
    Map response =await getDynamicData(
        UrlConfig.user,"/api/user/upload","post",formData: formData);
   return response;
  }

如果是字符串类型的,那就说明后端还有另外的一个接口上传图片到云服务器上面后前端会获得一个图片的地址,那么这个时候我们就只需要把这个字符串类型的地址传给后端就可以了。

4)在组件中使用这个方法

SizedBox(
    width: 200.0,
    height: 100.0,
    child: FloatingActionButton(
           elevation:0,
           backgroundColor:Color(0xE6E6E6E6),
           onPressed: getImage,
           tooltip: 'Pick Image',
           child: _image == null? Image.asset(
                 "assets/user/huzhao_pass.png",
                ) : Image.file(_image),
            ),
),

2.Flutter项目时间格式化

描述:Flutter版本的时间处理(多少天前,多少小时前,多少分钟前,多少秒前)
例如:

获取到的时间当前时间
2020-12-21 15:30:302020-12-24 15:30:30

那么页面上将显示3天前
以下是代码:

  getnoticeTime(str){
    if(str!='' ){
      var arr = str.split(" ");
      if(this.isToday(arr[0])){
        DateTime d = DateTime.now();
        var h = d.hour;
        var m = d.minute;
        var s = d.second;
        var hour = arr[1].split(':');
        if(h-hour[0]>1){
          return (h-hour[0]).toString()+"小时前";
        }
        else {
          if(m-hour[1]>=1){
            return (h-hour[0]).toString()+"分钟前";
          }
          else{
            return (s-hour[2]).toString()+"秒前";
          }
        }
      }
      else {
        var d = DateTime.now();
        var time = d.toString().split(' ')[0];
        var daynum = this.DateDiff(time,arr[0]);
        return (daynum).toString()+"天前";
      }
    }
  }
  // 判断两个时间相差多少天,此处需要注意的是difference这个方法只能传入时间格式的参数进行比较,所以前面需要一步转换的过程
  DateDiff(sDate1, sDate2) {  //sDate1和sDate2是yyyy-MM-dd格式
    var time = DateTime.parse(sDate1);
    var time2 = DateTime.parse(sDate2);
    var time3 = time.difference(time2).inDays;

    return time3;  //返回相差天数
  }
//判断是不是今天
  isToday(str){
    var d = DateTime.now();
    return str == (d.toString().split(' ')[0]);
  }

3.Flutter中将组件生成图片保存到手机相册。

1)安装依赖包(在pubspec.yaml文件添加插件)

image_gallery_saver安装1.5.0版本

  # 权限控制插件
  permission_handler: 5.0.1
  permission_handler_platform_interface: ^2.0.1
  # 文件保存插件
  image_gallery_saver: 1.5.0

添加以上代码以后需要安装哦

flutter pub get

2)android和ios配置

(1)ios 修改文件【在ios/Runner/Info.plist添加以下代码】
	<key>NSPhotoLibraryUsageDescription</key>
 	<string></string>
    <key>NSPhotoLibraryAddUsageDescription</key>
    <string>请允许APP保存图片到相册</string>
(2)android 修改文件【在android/app/src/main/AndroidManifest.xml添加以下代码】
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

3)将需要生成图片的组件用RepaintBoundary包裹

GlobalKey globalKey = GlobalKey();
RepaintBoundary(
      key: globalKey,
      child:Text('我要生成图片'),
      )

4)保存图片到相册【再点击事件中调用下面这个方法】

 /// 保存图片
  static Future<void> saveImage(GlobalKey globalKey) async {
    RenderRepaintBoundary boundary =
    globalKey.currentContext.findRenderObject();
    var image = await boundary.toImage(pixelRatio: 6.0);
    ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    Uint8List pngBytes = byteData.buffer.asUint8List();
    // final result = await ImageGallerySaver.saveImage(pngBytes,
    //     quality: 60, name: "hello");
    // if (result) {
    //   print('ok');
    //   // toast("保存成功", wring: false);
    // } else {
    //   print('error');
    // }

    if (Platform.isIOS) {
      var status = await Permission.photos.status;
      if (status.isUndetermined) {
        Map<Permission, PermissionStatus> statuses = await [
          Permission.photos,
        ].request();
        saveImage(globalKey);
      }
      if (status.isGranted) {
        final result = await ImageGallerySaver.saveImage(pngBytes,
            quality: 60, name: "hello");
        if (result) {
          print('ok');
          // toast("保存成功", wring: false);
        } else {
          print('error');
          // toast("保存失败");
        }
      }
      if (status.isDenied) {
        print("IOS拒绝");
      }
    } else if (Platform.isAndroid) {
      var status = await Permission.storage.status;
      if (status.isUndetermined) {
        Map<Permission, PermissionStatus> statuses = await [
          Permission.storage,
        ].request();
        saveImage(globalKey);
      }
      if (status.isGranted) {
        print("Android已授权");
        final result = await ImageGallerySaver.saveImage(pngBytes, quality: 60);
        if (result != null) {
          print('ok');
          // toast("保存成功", wring: false);
        } else {
          print('error');
          // toast("保存失败");
        }
      }
      if (status.isDenied) {
        print("Android拒绝");
      }
    }
  }

5)完整的保存图片的文件

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:interviewer_app/common/component_index.dart';
// 一定要引入这三个插件
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:permission_handler_platform_interface/permission_handler_platform_interface.dart';
import 'package:permission_handler/permission_handler.dart';

import 'package:flutter/services.dart';
import 'dart:ui' as ui;
import 'dart:typed_data';
import 'dart:io';

class ShareJob extends StatefulWidget {
  const ShareJob({Key key, this.searchKey}) : super(key: key);
  final String searchKey;


  @override
  State<StatefulWidget> createState() {

    return new _ShareJobState();
  }
}

class _ShareJobState extends State<ShareJob> {
// globalKey 在这里设置
  GlobalKey globalKey = GlobalKey();
  Uint8List newPngBytes;

  Widget shareImage() {
    return
      RepaintBoundary(
      key: globalKey,
      child:
      Container(

        child:
        // 图片
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            Container(
              alignment: Alignment.center,
              decoration: BoxDecoration(
                color: Color(0xFF5B9AFF),
                boxShadow:[
                BoxShadow(
                    color: Color(0x1A000000),
                    offset: Offset(0, 5.0),
                    blurRadius: 24.0
                ),
                  ]),

              width: MediaQuery.of(context).size.width * 0.6,

              child:
              Column(
                children: [
                  Gaps.vGap25,
                  Text('热招职位', style: TextStyle(fontSize: 22, color: Colors.white, fontWeight: FontWeight.w300),),
                  Gaps.vGap25,
                  Container(
                    margin: EdgeInsets.only(bottom: 22,left: 15,right: 15),
                    // padding: EdgeInsets.only(bottom: 22,left: 15,right: 15),
                    alignment: Alignment.center,
                    decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(10.0),
                        boxShadow:[
                          BoxShadow(
                              color: Color(0x1A000000),
                              offset: Offset(0, 5.0),
                              blurRadius: 24.0
                          ),
                        ]),
                    // padding: EdgeInsets.all(10),
                    // margin: EdgeInsets.only(bottom: 6),
                    // width: MediaQuery.of(context).size.width * 0.6,
                    // height: 305,
                    child: Column(
                      children: [
                        Gaps.vGap25,
                        Gaps.vGap10,
                        Text('测试工程师', style: TextStyle(fontSize: 15, color: Color(0xFF313753), fontWeight: FontWeight.w500),),
                        Gaps.vGap10,
                        Text('15k-20K | 上海', style: TextStyle(fontSize: 15, color: Color(0xFFF4A25A), fontWeight: FontWeight.w500),),
                        Gaps.vGap10,
                        Text('公司名', style: TextStyle(fontSize: 10, color: Color(0xFF313753), fontWeight: FontWeight.w400),),
                        Gaps.vGap15,
                        Image.asset(Utils.getImgPath('checked'),
                            width: 115.0),
                        Gaps.vGap25,
                        Text('长按查看职位详情', style: TextStyle(fontSize: 9, color: Color(0xFF313753), fontWeight: FontWeight.w400),),
                        Gaps.vGap25,
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),

      )
    );
  }

  /// 保存图片
  static Future<void> saveImage(GlobalKey globalKey) async {
    RenderRepaintBoundary boundary =
    globalKey.currentContext.findRenderObject();
    var image = await boundary.toImage(pixelRatio: 6.0);
    ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    Uint8List pngBytes = byteData.buffer.asUint8List();
    // final result = await ImageGallerySaver.saveImage(pngBytes,
    //     quality: 60, name: "hello");
    // if (result) {
    //   print('ok');
    //   // toast("保存成功", wring: false);
    // } else {
    //   print('error');
    // }

    if (Platform.isIOS) {
      var status = await Permission.photos.status;
      if (status.isUndetermined) {
        Map<Permission, PermissionStatus> statuses = await [
          Permission.photos,
        ].request();
        saveImage(globalKey);
      }
      if (status.isGranted) {
        final result = await ImageGallerySaver.saveImage(pngBytes,
            quality: 60, name: "hello");
        if (result) {
          print('ok');
          // toast("保存成功", wring: false);
        } else {
          print('error');
          // toast("保存失败");
        }
      }
      if (status.isDenied) {
        print("IOS拒绝");
      }
    } else if (Platform.isAndroid) {
      var status = await Permission.storage.status;
      if (status.isUndetermined) {
        Map<Permission, PermissionStatus> statuses = await [
          Permission.storage,
        ].request();
        saveImage(globalKey);
      }
      if (status.isGranted) {
        print("Android已授权");
        final result = await ImageGallerySaver.saveImage(pngBytes, quality: 60);
        if (result != null) {
          print('ok');
          // toast("保存成功", wring: false);
        } else {
          print('error');
          // toast("保存失败");
        }
      }
      if (status.isDenied) {
        print("Android拒绝");
      }
    }
  }




  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(title: Text('分享职位'), titleSpacing: 0, centerTitle: true),
      body: SingleChildScrollView(
        child: Container(
          child: Column(children: [
            Gaps.vGap25,
            Row(
              children: [
                // http://images.shejidaren.com/wp-content/uploads/2020/03/36365-4.png
                // IconButton(
                //   iconSize: 22,
                //   icon: const Icon(Icons.close),
                //   onPressed: (){
                //   },
                // )
                Gaps.hGap30,
                Gaps.hGap10,
                Gaps.hGap10,
                Column(
                  children: [
                    Container(
                      decoration: new BoxDecoration(
                        color: Cor.roundbg_1,
                        borderRadius: BorderRadius.circular(100),
                      ),
                      padding: EdgeInsets.all(10),
                      margin: EdgeInsets.only(bottom: 6),
                      width: 60,
                      height: 60,
                      child: Image.network(
                          'http://images.shejidaren.com/wp-content/uploads/2020/03/36365-4.png'),
                    ),
                    Text(
                      '微信好友',
                      textAlign: TextAlign.center,
                      style: TextStyle(color: Cor.black_1, fontSize: 14),
                    )
                  ],
                ),

                Gaps.hGap30,
                Gaps.hGap10,
                Gaps.hGap10,
                Column(
                  children: [
                    Container(
                      decoration: new BoxDecoration(
                        color: Cor.roundbg_1,
                        borderRadius: BorderRadius.circular(100),
                      ),
                      padding: EdgeInsets.all(10),
                      margin: EdgeInsets.only(bottom: 6),
                      width: 60,
                      height: 60,
                      child: Image.network(
                          'https://www.sj520.cn/sc/ima/weixin_sj520_11.jpg'),
                    ),
                    Text(
                      '朋友圈',
                      textAlign: TextAlign.center,
                      style: TextStyle(color: Cor.black_1, fontSize: 14),
                    )
                  ],
                ),
              ],
            ),
            Gaps.vGap20,
            // 灰色横线
            Container(
              decoration: new BoxDecoration(color: Cor.roundbg_1),
              width: double.infinity,
              height: 10,
            ),
            Gaps.vGap15,
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                Text(
                  '已生成朋友圈图片',
                  textAlign: TextAlign.center,
                  style: TextStyle(color: Cor.black_1.withOpacity(0.65), fontSize: 14),
                ),
              ],
            ),
            Gaps.vGap15,
            shareImage(),
            Gaps.vGap15,
            Gaps.vGap10,
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                RaisedButton(
                    color: Cor.blue_1,
                    highlightColor: Colors.blue[100],
                    colorBrightness: Brightness.dark,
                    splashColor: Cor.blue_2,
                    padding: EdgeInsets.only(left: 34,right: 34),
                    child: Text(
                      "保存至相册",
                      style: TextStyle(color: Colors.white, fontSize: 14),
                    ),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(20.0)),
                    onPressed: () async {

                      print('------');
                      print(globalKey.currentContext);
                      // createImageFromRepaintBoundary(globalKey);
                      // final g = createImageFromWidget(saveImage());
                      // print(g);
                      saveImage(globalKey);
                    },
                    ),
              ],
            ),
            Gaps.vGap25,
            Gaps.vGap25,

          ]),
        ),
      ),
    );
  }
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,让我来回答你的问题。 对于获取Android照片地址,可以使用flutter中的image_picker插件来实现。首先在pubspec.yaml文件中添加依赖: ``` dependencies: image_picker: ^0.6.7+22 ``` 然后在需要获取照片的位置调用以下代码即可: ```dart import 'package:image_picker/image_picker.dart'; final picker = ImagePicker(); final pickedFile = await picker.getImage(source: ImageSource.gallery); if (pickedFile != null) { final String path = pickedFile.path; // do something with the image path } ``` 对于Flutter项目安卓配置启动图片,可以在Android的项目目录下的`android/app/src/main/res`文件夹中放置启动图片。具体命名规则和尺寸可以参考Flutter官方文档:https://flutter.dev/docs/development/ui/advanced/splash-screen。在Android的`AndroidManifest.xml`文件中添加以下代码即可: ```xml <application android:name="io.flutter.app.FlutterApplication" android:icon="@mipmap/ic_launcher" android:label="your_app_name" android:theme="@style/LaunchTheme"> <activity android:name=".MainActivity" android:launchMode="singleTop" android:theme="@style/Theme.AppCompat.Light.NoActionBar" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background" /> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> ``` 其中`@drawable/launch_background`指的是启动图片的名称。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值