フラッターミキシング:Androidネイティブでフラッターをミキシング

現在、「Xianyu」クライアントは商品詳細ページに純粋なフラッターで書かれています。1ページに純粋なフラッターを書くのは問題ありません。ところで、ページが正しいかどうかを簡単に識別する方法について説明します。 Flutterまたはネイティブ(知っている場合は厳密ではありません。Flutterの場合、RNもこのようになるため):

  1. 電話の「開発者モード」をオンにします
  2. 「レイアウト境界を表示」をオンにします
  3. APPに切り替えます

「Xianyu」の商品一覧ページと商品詳細ページを例にとってみましょう。

商品一覧ページと商品詳細ページ

商品一覧ページと商品詳細ページ

次に、レイアウト境界線表示を開くと、Xianyuの製品リストページ(左)がネイティブに記述されているため、レイアウトレイヤーが表示されます。色が濃いほどレイアウトレイヤーが多くなり、製品の詳細ページ(右)が表示されます。はFlutterによって作成され、レイアウトのレイヤーは1つだけです。

レイアウト境界

レイアウト境界

さて、余談の後、前の「毎日」の例を使用して、AndroidでFlutterのミキシングを始めましょう。

計画はこれです:

  • ツールバーを含む外部UIフレームワークをネイティブに転送して処理します
  • Flutterは、ListView、日報データ要求ロジックなどを処理します。

これは基本的に、サブシンプルな混合コンパイルの例です。

最も簡単な。公式のFlutterの例(生肉の警告)も数えます:https//github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps

新しいフラッターモジュール

ネイティブコードにFlutterを混在させる場合は、コマンドラインから正式に作成されたModuleをFlutterに作成する必要がありますが、Android StudioのFlutterプラグインもこの機能を提供し、より直感的であるため、例としてAndroidStudioを示します。 :

新しいフラッターモジュール

新しいフラッターモジュール

次のプロジェクトパス、名前など:

フラッターモジュールのパス構成

フラッターモジュールのパス構成

次に、パッケージ名を設定し、もう一度[完了]をクリックします。

新しいAndroidプロジェクト

Flutter Moduleの同じ親ディレクトリに新しいAndroidプロジェクトを作成します。既存のプロジェクトに問題がなければ、同じことが言えます。

新しいAndroidプロジェクト

新しいAndroidプロジェクト

次に、ずっと行きます。

AndroidプロジェクトにFlutterを導入

作成したAndroidプロジェクトのsettings.gradleに次のコードを追加します。

1 
2 
3 
4 
5
setBinding(new Binding([gradle:this]))                                  
evaluate(new File(                                                       
  settingsDir.parentFile、                                                
  'flutter_daily_module / .android / include_flutter.groovy'                           
))

これsettingsDir.parentFileは、flutter_daily_module前に作成したFlutterModuleディレクトリである現在のディレクトリの親ディレクトリ表します。

[同期]をクリックすると、もう1つのFlutterライブラリモジュールが表示されます。

フラッターモジュール

フラッターモジュール

次に、アプリケーションモジュールのBuild.gradleで紹介したライブラリに依存します。

1
実装プロジェクト( ':flutter')

AndroidのネイティブコードがFlutterを呼び出す

簡単なデモから始めましょう。

Flutterのコードを次のように変更しました。

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21
import'dart:ui '; 
import'package:flutter / material.dart '; 

void main()=> runApp(_widgetForRoute(window.defaultRouteName)); 

Widget _widgetForRoute(String route){ 
  switch(route){ 
    case'route1 ':
      return Center(
        child:Text(' route:$ route '、textDirection:TextDirection.ltr)、
      ); 
    case'route2 ':
      return Center(
        child:Text(' route:$ route '、textDirection:TextDirection.ltr)、
      ); 
    デフォルト:
      return Center(
        child:Text( 'Unknown route:$ route'、textDirection:TextDirection.ltr)、
      ); 
  } 
}

上記のコードはウィジェットを返します。入力パラメーターがの場合、ウィジェットroute1の中央に表示されますroute: router1

Androidプロジェクトによってデフォルトで生成されるMainActivityで、route1を表示してみましょう。

1 
2 
3 
4 
5 
6 
7 
8 
9
ビューflutterView = Flutter.createView(
        MainActivity.this、
        getLifecycle()、
        "route1" 
); 
FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(600、800); 
layout.leftMargin = 100; 
layout.topMargin = 400; 
addContentView(flutterView、layout);

ネイティブAndroidプロジェクトを実行すると、次の効果が見られます。

FlutterViewランニングエフェクト

FlutterViewランニングエフェクト

次のコードに示すように、FlutterViewはそれを使用する唯一の方法ではありません。FlutterFragmentを介してFlutterを呼び出す方法もあります。

1 
2 
3
FragmentTransaction FragmentTransaction = getSupportFragmentManager()。beginTransaction(); 
FragmentTransaction.replace(R.id.fl_flutter_view、Flutter.createFragment( "route1")); 
FragmentTransaction.commit();

これfl_flutter_viewは、Androidのxmlで定義されたFrameLayoutに対応します。

1 
2 
3 
4
<FrameLayout 
    android:id = "@ + id / fl_flutter_view" 
    android:layout_width = "match_parent" 
    android:layout_height = "match_parent" />

実行中の効果チャートは次のとおりです。

FlutterFragmentランニングエフェクト

FlutterFragmentランニングエフェクト

Androidネイティブの外部フレームワークに埋め込まれたFlutter日報リスト

上記の手順を完了した後、AndroidでFlutterを呼び出す方法をすでに理解しています。以下では、この「外枠」に実際の一連の記事の「毎日」のリストページを埋め込みます。

「毎日」の純粋なFlutterプロジェクトのソースコード:https
//github.com/KevinWu1993/DailyFlutter

まず、Flutterのリストページのメインコードをflutter_daily_moduleに同期させましょう。

元の「デイリー」main.dartコードは次のとおりです。

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17
import'package:flutter / material.dart '; 
import'package:zhihudaily / daily / daily_page.dart '; 

void main()=> runApp(MyApp()); 

class MyApp extends StatelessWidget { 
  @override 
  Widget build(BuildContext context){ 
    return MaterialApp(
      title: '日报'、
      theme:ThemeData(
        primarySwatch:Colors.blue、
      )、
      home:DailyPage(title: '日报')、
    ); 
  } 
}

FlutterModuleのmain.dartを次のように変更しました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_daily_module/daily/daily_page.dart';

void main() => runApp(_widgetForRoute(window.defaultRouteName));

Widget _widgetForRoute(String route) {
  switch (route) {
    case 'dailyInNative':
      return MaterialApp(
        title: '日报',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: DailyPage(title: '日报', isShowToolbar: false,),
      );
    default:
      return MaterialApp(
        title: '日报',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: DailyPage(title: '日报'),
      );
  }
}

要注意的是default选项,因为Flutter Module也是可以独立运行的,所以留着这个case。

同样的在DailyPage这一个Widget的构造方法里面,增加一个可选“是否显示Toolbar”的参数,目的是在独立运行flutter项目的时候显示状态栏,而在作为library module混编进Android的时候隐藏Toolbar,使用Android原生的Toolbar。

1
DailyPage({Key key, this.title, this.isShowToolbar = true}) : super(key: key);

对于Flutter Toolbar,在DailyPage中构建的方法如下:

1
2
3
4
5
6
7
8
Widget _buildAppBar(BuildContext buildContext) {
  if (widget.isShowToolbar)
    return new AppBar(
      title: Text(widget.title),
    );
  else
    return null;
}

完成上述步骤后,在Android原生代码中调用如下:

1 
2 
3
FragmentTransaction FragmentTransaction = getSupportFragmentManager()。beginTransaction(); 
FragmentTransaction.replace(R.id.fl_flutter_view、Flutter.createFragment( "dailyInNative")); 
FragmentTransaction.commit();

日報リストの埋め込みが完了したので、実行してみましょう。

ネイティブランニング効果

ネイティブランニング効果

Flutterスタンドアロンモードで実行すると、次のようになります。

フラッター独立操作効果

フラッター独立操作効果

画像も真実もありません。この記事をレイアウト境界の比較図で終了しましょう。ツールバーに注意してください。1つはネイティブで、もう1つはFlutterです。

レイアウト境界の比較

レイアウト境界の比較

著者:ケビンウー

記事のリンク:https//kevinwu.cn/p/964c6c3/

 

おすすめ

転載: blog.csdn.net/MYBOYER/article/details/90737342