5分钟搞定Flutter与Android 的交互(内附大量Flutter学习资源)

本文介绍了Flutter与Android的交互过程,包括Android项目配置Flutter依赖、原生界面加载Flutter页面以及PlatformChannel的三种类型:BasicMessageChannel、MethodChannel和EventChannel的使用。通过实例展示了如何在Android活动中加载Flutter页面、实现双方的通信,并提供了Flutter系列教程链接。
摘要由CSDN通过智能技术生成

码个蛋(codeegg)第 743 次推文

Flutter 说到底只是一个 UI 框架,很多功能都需要通过原生的 Api 来实现,那么就会涉及到 Flutter 和 Native 的交互,因为本人不懂 iOS 开发,所以只能讲下 Flutter 同 Android 的交互。

Android项目配置Flutter依赖

既然是互相交互,那么需要准备一个 Android 项目。接着就需要创建 flutter module,让 Android 项目依赖,创建的方法可以参考官网 Flutter Wiki,虽然是官网提供的方法,但是完全按照这个步骤来,还是会有坑的,这边就慢慢一步步解决坑。

如果你用的是 Android Studio 进行开发的话,直接打开底部的 Terminal,直接创建 flutter module 依赖

flutter create -t module flutter_native_contact 至于 module 名可以随意填写,module 创建完后结构大概是这样的

flutter module.png

接着切换到 module 下的 .android 文件夹,接着有坑来了,官网提供的方法是 ./gradlew flutter:assembleDebug 可能会提示命令不存在,那么直接通过 gradlew flutter:assembleDebug 来运行,等它自动跑完后,打开根目录下的 settings.gradle 文件,加入官网提供的 gradle 代码

setBinding(new Binding([gradle: this]))                             // new
evaluate(new File(                                                  // new
  settingsDir.parentFile,                                           // new
  'flutter_native_contact/.android/include_flutter.groovy'          // new
))                                                     // new

你以为这里没坑,真是图样图森破,没坑是不可能的,编译器大爷可能会给你甩这么个错误

很明显可以看出是找不到我们的文件,所以把文件名路径给补全

evaluate(new File(                                                      // new
  settingsDir.parentFile,                                               // new
  'FlutterNativeContactDemo/flutter_native_contact/
   .android/include_flutter.groovy' // 这里补全路径
))

接着打开原有项目下,原有项目下,原有项目下的 app 中的 build.gradle 文件,在 android 下加上如下代码

compileOptions {
  sourceCompatibility 1.8
  targetCompatibility 1.8
}

这个必须要加,不要问为什么,我也不知道为什么,最后在项目下添加 flutter module 的依赖就完成了。这个过程告诉我们一个什么道理呢?*不要以为官网的都对,官网讲的也不是完全可信的,时不时给你来个坑就能卡你老半天。

原生界面加载Flutter页面

那么如何在原生界面显示 Flutter 界面呢,这个就需要通过 FlutterView 来实现了,Flutter 这个类提供了 createView 和 createFragment 两个方法,分别用于返回 FlutterView 和 FlutterFragment 实例,FlutterFragment 的实现原理也是通过 FlutterView 来实现的,可以简单看下 FlutterFragment 的源码

/**
 * A {@link Fragment} managing a {@link FlutterView}.
 *
 * <p><strong>Warning:</strong> This file is auto-generated by Flutter tooling.
 * DO NOT EDIT.</p>
 */
public class FlutterFragment extends Fragment {
  public static final String ARG_ROUTE = "route";
  private String mRoute = "/";

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 获取传入的路由值,默认为 '/'
    if (getArguments() != null) {
      mRoute = getArguments().getString(ARG_ROUTE);
    }
  }

  @Override
  public FlutterView onCreateView(@NonNull LayoutInflater inflater,
                            ViewGroup container, Bundle savedInstanceState) {
    
    // 最后还是挺过 createView 方法来生成页面,只不过直接放在 fragment,
    // 放在 fragment 会比直接 使用 FlutterView 更方便管理,例如实现 ViewPager 等
    return Flutter.createView(getActivity(), getLifecycle(), mRoute);
  }
}

CreateFragment方式加载

在原生页面显示 Flutter 界面的第一种方式就是加载 FlutterFragment,看个比较简单的例子吧

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- 这个布局用于加载 fragment -->
    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/flutter_fragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="20dp"
        android:layout_marginBottom="50dp"
        android:src="@drawable/ic_add_white_36dp"
        app:fabSize="auto"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

</android.support.constraint.ConstraintLayout>

在 Activity 可以直接通过返回 FlutterFragment 加载到 FrameLayout 即可

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        supportFragmentManager.beginTransaction()
            .add(R.id.fragment_container,
                 Flutter.createFragment("route_flutter"))
            .commit()
    }
}

这样就把 Flutter 页面加载到原生界面了,会通过传递的路由值在 dart 层进行查找,所以接着就需要编写 Flutter 界面

/// runApp 内部值也可以直接传入 _buildWidgetForNativeRoute 方法
/// 这边在外层嵌套一层 MaterialApp 主要是防止一些不必要的麻烦,
/// 例如 MediaQuery 这方面的使用等
void main() => runApp(FlutterApp());

class FlutterApp extends StatelessWidget {
  @override
  Widget 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值