likes
comments
collection
share

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

作者站长头像
站长
· 阅读数 2
  • 我们在开发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调用原生页面