Flutter 與原生交互的實(shí)現(xiàn)方式

Flutter 框架既提供了與原生交互的接口,也支持原生項(xiàng)目嵌入 Flutter蝗罗。雖然支持桐腌,但是 Flutter 其實(shí)不建議在原生項(xiàng)目中嵌入 Flutter,因?yàn)?Flutter 需要渲染引擎的支持将饺,會比較重量級,不像嵌入 Web 頁這么輕便痛黎。下面以 Flutter 調(diào)起原生相冊為例予弧,我們介紹一下 Flutter 調(diào)起原生的方式。

自己實(shí)現(xiàn) Flutter 調(diào)起原生相冊

  • Flutter 代碼
MethodChannel _methodChannel = MethodChannel('mine_page/method');
File? _avatarFile;

void initState() {
    super.initState();
    _methodChannel.setMethodCallHandler((call) {
      if (call.method == 'imagePath') {
        setState(() {
          //獲取圖片本地路徑并進(jìn)行截取
          String imagePath = call.arguments.toString().substring(7);
          _avatarFile = File(imagePath);
        });
      }
      return Future((){});
    });
GestureDetector(
              onTap: () {
                _methodChannel.invokeMapMethod('picture');
              },
              child: Container(
                width: 70,
                height: 70,
                // 設(shè)置圓角屬性
                decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(10),
                    image: DecorationImage(
                        image: (_avatarFile == null)
                            ? AssetImage('images/ChenXi.JPG') as ImageProvider : FileImage(_avatarFile ?? File('')),
                    )
                ),
              ),
            ),
  • iOS 代碼實(shí)現(xiàn)
@interface AppDelegate () <UINavigationControllerDelegate, UIImagePickerControllerDelegate>

/// methodChannel
@property (nonatomic, strong, nullable) FlutterMethodChannel *methodChannel;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [GeneratedPluginRegistrant registerWithRegistry:self];
    
    FlutterViewController *vc = (FlutterViewController *)self.window.rootViewController;
    self.methodChannel = [FlutterMethodChannel methodChannelWithName:@"mine_page/method" binaryMessenger:vc];
    UIImagePickerController *pickerVc = [[UIImagePickerController alloc] init];
    pickerVc.delegate = self;
    [self.methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
        if ([call.method isEqualToString:@"picture"]) {
            [vc presentViewController:pickerVc animated:YES completion:nil];
        }
    }];
    
    // Override point for customization after application launch.
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info {
    [picker dismissViewControllerAnimated:YES completion:^{
        NSString *imagePath = [NSString stringWithFormat:@"%@",info[@"UIImagePickerControllerImageURL"]];
        [self.methodChannel invokeMethod:@"imagePath" arguments:imagePath];
    }];
}

當(dāng)我們想用 Flutter 調(diào)起原生相冊湖饱,并且更換頭像的話我們需要經(jīng)過以下幾個步驟:

  1. Flutter 與原生交互的時候借助一個類 MethodChannel掖蛤,所以 Flutter 代碼中首先我們定義了一個變量 _methodChannel,并傳入字符串 mine_page/method井厌,就是一個標(biāo)識
  2. 為頭像添加點(diǎn)擊實(shí)現(xiàn)蚓庭,并調(diào)用 _methodChannelinvokeMapMethod 方法,傳入 picture仅仆,picture 就是作為打開相冊的標(biāo)識器赞,可以我們自己隨意定義。
  3. 同樣在 oc 代碼中我們也要定義一個 FlutterMethodChannel 類型的屬性 methodChannel蝇恶,調(diào)用 methodChannelWithName 方法創(chuàng)建 methodChannel 對象拳魁,傳入的第一個參數(shù)要與 Flutter 中的字符保持一致惶桐,第二個參數(shù)我們傳的是 window 的根控制器撮弧。
  4. 實(shí)現(xiàn) setMethodCallHandler 方法,當(dāng) Flutter 中頭像點(diǎn)擊事件執(zhí)行的時候就會調(diào)用 setMethodCallHandler 中的回調(diào)姚糊,這里我們判斷 call.method 是否為 picture贿衍。
  5. block 中調(diào)起 UIImagePickerController,并把 pickerVc 的代理設(shè)置為 self救恨。
  6. 實(shí)現(xiàn)選中圖片的代理方法贸辈,并在代理方法中執(zhí)行 [self.methodChannel invokeMethod:@"imagePath" arguments:imagePath],這里 imagePath 為圖片的本地路徑肠槽。這里原生也是調(diào)用 invokeMethod 方法與 Flutter 進(jìn)行通訊擎淤。
  7. Flutter 代碼中實(shí)現(xiàn) setMethodCallHandler 方法奢啥,當(dāng)?shù)?6 步執(zhí)行完后就會執(zhí)行閉包,在這里可以獲取到圖片的路徑嘴拢,把路徑傳給 File 類桩盲,創(chuàng)建變量 _avatarFile。最后調(diào)用 setState 方法席吴,刷新頁面赌结。
  8. 頭像部件中 image 屬性進(jìn)行判斷,當(dāng) _avatarFile 有值的時候就顯示本地相冊選中圖片孝冒,否則就使用默認(rèn)圖片柬姚。

使用三方組件實(shí)現(xiàn)調(diào)起相冊功能

Flutter 官方為我們提供了一個三方組件 image_picker 來實(shí)現(xiàn)調(diào)起相冊的功能,這里我們用 image_picker 來實(shí)現(xiàn)一下庄涡。

// 頭像
            GestureDetector(
              onTap: () {
                _pickImage();
              },
void _pickImage() async {
    try {
      XFile? file = await ImagePicker().pickImage(source: ImageSource.gallery);
      setState(() {
        _avatarFile = File(file?.path ?? '');
      });
    }catch (e) {
      print(e.toString());
      setState(() {
        _avatarFile = null;
      });
    }
  }

使用三方組件的話我們只需要實(shí)現(xiàn) _pickImage 方法中的這些代碼就可以實(shí)現(xiàn)相冊選擇的功能量承,而且原生工程不需要改代碼,但是需要注意的是 iOS 原生項(xiàng)目需要配置 info.plist 中的相冊權(quán)限穴店。使用三方庫的好處就是運(yùn)行項(xiàng)目的時候會先執(zhí)行 pod install宴合,把原生相關(guān)的代碼給下載到工程,三方庫中不光有 dart 代碼迹鹅,而且也有原生相關(guān)的代碼卦洽。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市斜棚,隨后出現(xiàn)的幾起案子阀蒂,更是在濱河造成了極大的恐慌,老刑警劉巖弟蚀,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚤霞,死亡現(xiàn)場離奇詭異,居然都是意外死亡义钉,警方通過查閱死者的電腦和手機(jī)昧绣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捶闸,“玉大人夜畴,你說我怎么就攤上這事∩咀常” “怎么了贪绘?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長央碟。 經(jīng)常有香客問我税灌,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任菱涤,我火速辦了婚禮苞也,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘粘秆。我一直安慰自己墩朦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布翻擒。 她就那樣靜靜地躺著氓涣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪陋气。 梳的紋絲不亂的頭發(fā)上劳吠,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機(jī)與錄音巩趁,去河邊找鬼痒玩。 笑死,一個胖子當(dāng)著我的面吹牛议慰,可吹牛的內(nèi)容都是我干的蠢古。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼别凹,長吁一口氣:“原來是場噩夢啊……” “哼草讶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起炉菲,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤堕战,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拍霜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嘱丢,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年祠饺,在試婚紗的時候發(fā)現(xiàn)自己被綠了越驻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡道偷,死狀恐怖缀旁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情试疙,我是刑警寧澤诵棵,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布抠蚣,位于F島的核電站祝旷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜怀跛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一距贷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吻谋,春花似錦忠蝗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至骇两,卻和暖如春速种,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背低千。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工配阵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人示血。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓棋傍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親难审。 傳聞我的和親對象是個殘疾皇子瘫拣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容