Flutter - 混合开发(二)Flutter使用第三方插件访问相册

 

详细代码参见Demo

Demo地址 -> wechat_demo

 

前面文章 9、Flutter - 项目实战 - 仿微信(三)我的页面 中最后提到头像从相册或拍照来实现变更的功能没有做,今天就来把项目实战中的 wechat_demo 中的调用相册变更头像实现一下

 

使用一个Flutter第三方插件

image_picker

flutter Android13 打开相册权限问题 flutter 读取相册_项目实战

注意:

当重新导入与原生相关的第三方插件时(例如访问相册、地图定位),需要重新启动工程。这时候会打印pod install。也就是走了一下iOS   pod导入第三方。cocoapod 在启动工程的时候才会

flutter Android13 打开相册权限问题 flutter 读取相册_第三方插件_02

 

import 'package:image_picker/image_picker.dart';

不在展示全部代码,可自行去GitHub下载源码或者去  9、Flutter - 项目实战 - 仿微信(三)我的页面   文章查看。

class _MinePageState extends State<MinePage> {
  File _avataFile;
  double _left_distance = 50;

  Widget headerWidget() {
    return Container(
      color: Colors.white,
      height: 205,
      child: Container(
//        color: Colors.yellow,
        margin: EdgeInsets.only(top: 100, bottom: 20),
        padding: EdgeInsets.all(10),
        child: Container(
          margin: EdgeInsets.only(left: 10),
//          padding: EdgeInsets.all(5),
//          color: Colors.red,
          child: Row(
            children: <Widget>[
              GestureDetector(
                onTap: _pickImage,
                child: Container(
                  width: 50,
                  height: 50,
                  //图片通过装饰器去设置圆角是不起作用的,应该设置在装饰器内的背景图
//                child: Image(image:AssetImage('images/Hank.png')),
                  decoration: BoxDecoration(
                    color: Colors.blue,
                    borderRadius:
                        BorderRadius.circular(10.0), //设置圆角,image没有这个属性
                    //fit 填充
                    image: DecorationImage(
                        image: _avataFile == null
                            ? AssetImage('images/新的朋友.png')
                            : FileImage(_avataFile),
                        fit: BoxFit.cover),
                  ),
                ), //头像
              ),
              Container(...),
              )
            ],
          ),
        ),
      ),
    );
  } //头部抽出来写个方法

  @override
  Widget build(BuildContext context) {...}

//  async 异步 配合 await 等待,让该方法内部就成了同步
//  getImage 是异步,不想写过多的.then等,所以等待转成同步
  void _pickImage() async {
//    ImagePicker.pickImage(source: null) //过期了

//  ImageSource.gallery 使用相册
    PickedFile file = await ImagePicker().getImage(source: ImageSource.gallery);
    setState(() {
      _avataFile = File(file.path);
    });
  }
}

定义一个Flie 用来接收选中的图片

File _avataFile;

image 显示的时候,根据File 文件是都为空判断进行显示

image: DecorationImage(
    image: _avataFile == null
    ? AssetImage('images/新的朋友.png')
    : FileImage(_avataFile),

 点击头像的方法里面进行调用Image_Picker 的方法

方法过期

flutter Android13 打开相册权限问题 flutter 读取相册_仿微信_03

ImagePicker.pickImage(source: null)

源码:

@Deprecated('Use imagePicker.getImage() method instead.')
static Future<File> pickImage(
    {@required ImageSource source,
    double maxWidth,
    double maxHeight,

通过源码可知标记方法过期的方式,在以后自己开发的时候就可以用

@Deprecated('Use imagePicker.getImage() method instead.')

用相机还是相册

ImagePicker().getImage(source: ImageSource.gallery);

源码

enum ImageSource {
  /// Opens up the device camera, letting the user to take a new picture.
  camera, //相机

  /// Opens the user's photo gallery.
  gallery, //相册
}

getImage 返回的是一个Future( 异步)

Future<PickedFile> getImage({
  @required ImageSource source,

由于返回的是异步的,我们需要再异步回调完成之后,去刷新UI

那么  async 异步 配合 await 等待,让该方法内部就成了同步
getImage 是异步,不想写过多的.then等,所以用等待转成同步

//  async 异步 配合 await 等待,让该方法内部就成了同步
//  getImage 是异步,不想写过多的.then等,所以等待转成同步
  void _pickImage() async {
//    ImagePicker.pickImage(source: null) //过期了

//  ImageSource.gallery 使用相册
    PickedFile file = await ImagePicker().getImage(source: ImageSource.gallery);
    setState(() {
      _avataFile = File(file.path);
    });
  }
}

这样就完了吗?NO,运行完一点击马上崩溃,同时没有错误反馈,没有打印报错信息。这是为什么呢?因为我们访问相册要授权,去xcode里面进行授权。

授权,根据自己需要。目前项目中只用了相册,只添加相册权限即可。我这里添加了相册和相机的权限,计划以后使用相机,所以先加上

flutter Android13 打开相册权限问题 flutter 读取相册_项目实战_04

然后再次运行就行

效果图:

flutter Android13 打开相册权限问题 flutter 读取相册_第三方插件_05

 

比调用iOS原生的来回发送消息简单多了

地图定位 location 等等更多第三方插件可以自行去 pub.dev 中查找