• 咱们在开发flutter中,通常会调用原生的一些功能,比如相机相册等,接下来就一起了解下吧。

1. Flutter调用相册

咱们在之前的微信项目头像增加一个手势

Flutter学习-31-Flutter调用原生页面
flutter中运用channel进行交互,我么定义一个MethodChannel

final MethodChannel _methodChannel = const MethodChannel('mine_page/method');

在手势的onTap中调用

_methodChannel.invokeListMethod('pictureMethod');

咱们打开iOS工程,一起记得在plist文件中增加权限,否则审核不会经过。

这儿留意要在info.plist

Flutter学习-31-Flutter调用原生页面
在appDelegate中增加

let vc:FlutterViewController = self.window.rootViewController as! FlutterViewController;//fluttevc
  
let metodChannel:FlutterMethodChannel = FlutterMethodChannel.init(name: "mine_page/method", binaryMessenger: vc.binaryMessenger);
  
 metodChannel.setMethodCallHandler {(call:FlutterMethodCall, result: @escaping FlutterResult) in
  if (call.method == "pictureMethod"){
   let pickVC: UIImagePickerController = UIImagePickerController.init();
  vc.present(pickVC, animated: true, completion: nil);
     }
   }

点击头像调用了原生的相册

Flutter学习-31-Flutter调用原生页面

这儿咱们要停掉项目再次运转,这个时分会XcodeBuild,咱们动了原生代码就要重新编译原生端。

  • 咱们要把原生的数据或许图片传递出去 咱们把vc和metodChannel设置全局的
@objc class AppDelegate: FlutterAppDelegate ,UIImagePickerControllerDelegate, UINavigationControllerDelegate{
  var vc:FlutterViewController?;
  var metodChannel:FlutterMethodChannel?;
 override func application(
  _ application: UIApplication,
  didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
 ) -> Bool {
  
   vc = self.window.rootViewController as? FlutterViewController;//fluttevc
   metodChannel = FlutterMethodChannel.init(name: "mine_page/method", binaryMessenger: self.vc!.binaryMessenger);
   metodChannel?.setMethodCallHandler {(call:FlutterMethodCall, result: @escaping FlutterResult) in
     if (call.method == "pictureMethod"){
       let pickVC: UIImagePickerController = UIImagePickerController.init();
       pickVC.delegate = self;
       self.vc?.present(pickVC, animated: true, completion: nil);
     
     }
   }
  GeneratedPluginRegistrant.register(with: self)
  return super.application(application, didFinishLaunchingWithOptions: launchOptions)
 }
 
  func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
   
    print(info);
  }
}

咱们打印下相片的信息,咱们需求的是UIImagePickerControllerImageURL

Flutter学习-31-Flutter调用原生页面
咱们接取下经过invokeMethod发送出去,这儿把url转换为string

let Str:NSURL = info[UIImagePickerController.InfoKey(rawValue: "UIImagePickerControllerImageURL")] as! NSURL;
      self.metodChannel?.invokeMethod("imagePath", arguments: Str.absoluteString);

咱们在flutter中进行接收

late File _avatarFile;
final MethodChannel _methodChannel = const MethodChannel('mine_page/method');
@override
void initState() {
  super.initState();
  _methodChannel.setMethodCallHandler((call) async{
    if (call.method == 'imagePath') {
      String imagePath = call.arguments.toString().substring(7);
      setState(() {
        _avatarFile = File(imagePath);
      });
    }else{
      return null; 
    }
  });
}

咱们进行判断是否存在

image: _avatarFile == null
    ? AssetImage('images/微信表情.png')
    : FileImage(_avatarFile),

Flutter学习-31-Flutter调用原生页面
这儿说咱们的类型不同报错AssetImageFileImage,咱们在外面包裹下

 image: _avatarFile == null
 ?const DecorationImage( image:
      AssetImage('images/微信表情.png'),
 fit: BoxFit.cover)
: DecorationImage(image:
    FileImage(_avatarFile!),
 fit: BoxFit.cover)

Flutter学习-31-Flutter调用原生页面
点击挑选头像

Flutter学习-31-Flutter调用原生页面

这儿首要介绍下调用iOS原生的相册,安卓的网上许多介绍。

2 image_picker

咱们能够运用 image_picker插件

Flutter学习-31-Flutter调用原生页面
咱们调用,能够挑选相册或许相机

Flutter学习-31-Flutter调用原生页面

void seletImage() async{
  XFile? file = await ImagePicker().pickImage(source: ImageSource.gallery);
  if( file != null) {
    setState(() {
      _avatarFile = File(file.path);
    });
  }else{
    setState(() {
      _avatarFile = null;
    });
  }
}

Flutter学习-31-Flutter调用原生页面

这样写有些问题,当咱们取消的时分,直接置空了之前的挑选。咱们原意是在挑选失败的时分把途径置空,咱们能够在挑选过错的时分不处理。

Flutter学习-31-Flutter调用原生页面