美文网首页
Flutter - FlutterActivity, 咱照葫芦画

Flutter - FlutterActivity, 咱照葫芦画

作者: Cosecant | 来源:发表于2019-11-26 14:39 被阅读0次

Flutter - FlutterActivity, 咱照葫芦画瓢

背景

由于历史原因,有一个老项目中使用了Flutter代码作为插件使用,但是也遗留了一个历史问题。先说明下这个问题:

首先我很早之前编写了一个BaseFlutterActivity类,是继承于AppCompatActivity的,其中它的子类的使用即是一个Activity对应一个Flutter的页面,是一对一的关系,并且只能一对一关系。但是现在我想把它弄成一个Activity对应N个Flutter页面,问题就来了,原来的Activity并不能处理页面的返回事件。

​ 头疼,但是也不能改之前的代码,不然会影响太多太多的Activity。那就“照葫芦画瓢”吧。想想,SDK中提供的FlutterActivity支持页面返回事件处理,那就复制它的代码吧。

复制SDK中提供的FlutterActivity的代码

  1. 需要按照它的实现某些接口 FlutterView.Provider, PluginRegistry, FlutterActivityDelegate.ViewFactory
  2. 注意合适的位置注册Plugin,包括自定义的和系统自动生成插件方法(GeneratedPluginRegistrant.registerWith(pluginRegistry) );
  3. 注意处理各种生命周期和事件--事件重写和调用;

注意

  1. 方法createFlutterView我重新实例化了一个FlutterView,这里是为了方便使用setInitialRoute, 如果不这么做,系统会自己调用默认的路由路径。
  2. 在调用这个自定义的FlutterActivity之前,需要先调用 ** FlutterMain.startInitialization(this); **,不然程序可能会闪退。

现在咱可以在这个Activity中使用ViewProvider做网络调用支援,也可以在MethodChannel做一些需要的相互调用的操作。

:-) 此处做个记录,防止忘记和再次踩坑!

open class BaseFlutterActivity() : AppCompatActivity(), FlutterView.Provider,
    PluginRegistry,
    FlutterActivityDelegate.ViewFactory {

    companion object {

        @JvmField
        val TAG = "FlutterActivity"

        /** 通讯频道名称 **/
        const val DefaultChannelName = "plugins.cosecant.flutter/page-assistant"

        /** 路由名称 **/
        const val ArgRouteName = "routeName"

        /**
         * 打开Flutter页面
         * @param context 上下文对象
         * @param routeName Flutter路由名称, 默认为:default
         */
        @JvmStatic
        fun start(context: Context, routeName: String = "default") = with(Bundle()) {
            putString(ArgRouteName, routeName)
            Router.forward(context, BaseFlutterActivity::class.java, data = this)
        }

    }

    private val delegate by lazy { FlutterActivityDelegate(this, this) }

    // These aliases ensure that the methods we forward to the delegate adhere
    // to relevant interfaces versus just existing in FlutterActivityDelegate.
    private val eventDelegate: FlutterActivityEvents = delegate
    private val viewProvider: FlutterView.Provider = delegate
    private val pluginRegistry: PluginRegistry = delegate

    /** 默认路由名称 **/
    protected open val activityRouteName = "default"

    /** 传递过来的路由名称 **/
    private val routeName by lazy {
        when {
            intent?.hasExtra(ArgRouteName) == true -> intent.getStringExtra(ArgRouteName)
                ?: activityRouteName
            intent?.extras?.containsKey(ArgRouteName) == true -> intent?.extras?.getString(
                ArgRouteName
            )
                ?: activityRouteName
            else -> activityRouteName
        }
    }

    /** method-channel **/
    protected var methodChannel: MethodChannel? = null

    override fun retainFlutterNativeView(): Boolean = false

    override fun createFlutterNativeView(): FlutterNativeView? = null

    override fun createFlutterView(context: Context?): FlutterView? = FlutterView(this).apply {
        setInitialRoute(routeName) //设置初始路径
        //注册插件
        GeneratedPluginRegistrant.registerWith(pluginRegistry)
        BarcodeProviderPlugin.registerWith(pluginRegistry)
        ZxingBarPluginRegistrant.registerWith(pluginRegistry)
        EnvironmentProviderPlugin.registerWith(pluginRegistry)
        addFirstFrameListener { onFlutterViewAttached() }
        layoutParams = WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT
        )
        setContentView(this)
    }

    override fun getFlutterView(): FlutterView = viewProvider.flutterView

    override fun <T> valuePublishedByPlugin(pluginKey: String?): T =
        pluginRegistry.valuePublishedByPlugin(pluginKey)

    override fun registrarFor(pluginKey: String?): Registrar =
        pluginRegistry.registrarFor(pluginKey)

    override fun hasPlugin(pluginKey: String?): Boolean = pluginRegistry.hasPlugin(pluginKey)

    @Override
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        eventDelegate.onCreate(savedInstanceState)
        initView() //初始化视图
        EventBus.getDefault().register(this)
    }

    /** 初始化视图 **/
    protected open fun initView() {
        initMethodChannel() //初始化MethodChannel
    }

    /** 初始化MethodChannel **/
    protected open fun initMethodChannel() {
        methodChannel = MethodChannel(flutterView, DefaultChannelName)
        methodChannel?.setMethodCallHandler { methodCall, result ->
            onHandleMethodChannelInvoke(methodCall, result)
        }
    }

    /** 此方法中在FlutterView加载完毕并显示第一贴的时候调用 **/
    protected open fun onFlutterViewAttached() {}

    /**
     * 处理MethodChannel回调
     * @param methodCall 方法回调参数
     * @param result 结果处理
     */
    protected open fun onHandleMethodChannelInvoke(
        methodCall: MethodCall?,
        result: MethodChannel.Result?
    ) {
        when (methodCall?.method) {
            "finish" -> { //关闭当前页面
                goBack()
                result?.success(null)
            }
        }
    }
        
    override fun onStart() {
        super.onStart()
        eventDelegate.onStart()
    }

    override fun onResume() {
        super.onResume()
        eventDelegate.onResume()
    }

    override fun onDestroy() {
        eventDelegate.onDestroy()
        super.onDestroy()
    }

    override fun onBackPressed() {
        if (!eventDelegate.onBackPressed()) {
            super.onBackPressed()
        }
    }

    override fun onStop() {
        eventDelegate.onStop()
        super.onStop()
    }

    override fun onPause() {
        super.onPause()
        eventDelegate.onPause()
    }

    override fun onPostResume() {
        super.onPostResume()
        eventDelegate.onPostResume()
    }

    // @Override - added in API level 23
    override fun onRequestPermissionsResult(requestCode: Int, @NonNull permissions: Array<String>, @NonNull grantResults: IntArray) {
        eventDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }

    override fun onActivityResult(
        requestCode: Int,
        resultCode: Int,
        data: Intent?
    ) {
        if (!eventDelegate.onActivityResult(requestCode, resultCode, data)) {
            super.onActivityResult(requestCode, resultCode, data)
        }
    }

    @SuppressLint("MissingSuperCall")
    override fun onNewIntent(intent: Intent?) {
        eventDelegate.onNewIntent(intent)
    }

    override fun onUserLeaveHint() {
        eventDelegate.onUserLeaveHint()
    }

    override fun onTrimMemory(level: Int) {
        eventDelegate.onTrimMemory(level)
    }

    override fun onLowMemory() {
        eventDelegate.onLowMemory()
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        eventDelegate.onConfigurationChanged(newConfig)
    }

    /** 页面返回 **/
    protected open fun goBack(): Unit =
        Router.back(this, enterAnimRes = R.anim.slide_in_left, exitAnimRes = R.anim.slide_out_right)

}

相关文章

网友评论

      本文标题:Flutter - FlutterActivity, 咱照葫芦画

      本文链接:https://www.haomeiwen.com/subject/ufbewctx.html