ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

在现有Android 项目中加入Flutter页面(1)FlutterActivity、FlutterView 、FlutterFragment

2021-11-03 15:01:32  阅读:256  来源: 互联网

标签:FlutterFragment title route FlutterView Flutter class import Android flutter


序、上半年准备在原有的项目中接入一些Flutter页面 。当时就是一个感受,一个字,真坑。

讲真的,我有一个大胆的猜测,大部分使用Flutter的项目,应该很少更新Flutter的版本。尽管Flutter已经更新到了***。怎么说呢?

接入时遇到的问题,搜索出来的博客几乎不能用,不能用包括类文件找不到,方法找不到,一运行报错。

气死我了。

1.原有的Android项目已经存在。

此处省略几个字。

2.在Android项目中创建 Flutter  的Module。

2.1File —— New —— New Module 

 当然也可以用命令行去创建,自行百度。

2.2据说要给setting.gradle 加入配置文件

 PS:Flutter 的 module 创建完最后,AndroidStudio就自己有了这块代码了,不需要手动去写这块东西。Binding 报错,不用管好吧。

PS:接下来打开一个 Flutter 的main.dart 文件,会报错,需要你去设置一下flutter SDK。就可以了。文件有提示,因为我设置完了,不能截图。

2.3可以先运行一下flutter 项目。

3.Android页面跳转到 Flutter页面

3.1创建一个FlutterActivity(配置清单文件记得加)

package com.supermax.flutter;

import io.flutter.embedding.android.FlutterActivity;

import android.os.Bundle;

public class FlutterActivityPage extends FlutterActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

3.2配置清单文件添加代码 FlutterActivity

 <activity
            android:name="io.flutter.embedding.android.FlutterActivity"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:theme="@style/AppThemeNoActionBar"
            android:windowSoftInputMode="adjustResize" />

3.3MainActivity 里面加入跳转代码

package com.supermax.flutter;

import androidx.appcompat.app.AppCompatActivity;
import io.flutter.embedding.android.FlutterActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    private Button btn_flutter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_flutter = findViewById(R.id.btn_flutter);

        btn_flutter.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //直接使用 FlutterActivity 进行跳转
//                startActivity(FlutterActivity
//                        .withNewEngine()
//                        .initialRoute("route")
//                        .build(MainActivity.this));
                
                //FlutterActivityPage 继承FlutterActivity
                startActivity(FlutterActivityPage
                        .withNewEngine()
                        .initialRoute("route")
                        .build(MainActivity.this));
            }
        });

    }
}

3.4main.dart 里面加入接收的代码


import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(_widgetForRoute(window.defaultRouteName));
}

Widget _widgetForRoute(String route) {
  print("111=" + route);
  switch (route) {
    case 'route':
      _toastMessage("111=" + route);
      return MyApp();
    default:
      return Center(
        child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
      );
  }
}

void _toastMessage(String title) {
  Fluttertoast.showToast(
      msg: title,
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.BOTTOM,
      timeInSecForIosWeb: 1,
      backgroundColor: Colors.black45,
      textColor: Colors.white,
      fontSize: 16.0);
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

PS:可以开始了各位。

运行,点击,跳转,完美。

4.Flutter 页面跳转到 Android页面,使用了 MethodChannel.MethodCallHandler

4.1写一个类实现 MethodChannel.MethodCallHandler,并重写onMethodCall方法

package com.supermax.flutter;

import android.app.Activity;
import android.content.Intent;
import android.util.Log;

import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterView;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;

/**
 * @Author yinzh
 * @Date 2021/11/3 14:33
 * @Description
 */
public class Flutter2AndroidHelp implements MethodChannel.MethodCallHandler {

    public static String CHANNEL_NAME = "com.supermax";

    private MethodChannel methodChannel;
    private FlutterView flutterView;
    private Activity mActivity;
    private Flutter2AndroidHelp() {

    }

    private static Flutter2AndroidHelp instance;


    public static Flutter2AndroidHelp getInstance() {
        if (instance == null) {
            synchronized (Flutter2AndroidHelp.class) {
                if (instance == null) {
                    instance = new Flutter2AndroidHelp();
                }
            }
        }
        return instance;
    }

    private Flutter2AndroidHelp(Activity activity) {
        this.mActivity = activity;
    }

    /**
     * 接收Flutter传来的指令,进一步处理
     * @param call
     * @param result
     */
    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
        if (call == null) {
            return;
        }

        Log.i("FlutterPluginJumpToAct", "method is " + call.method + " arguments is " + (call.arguments == null ? "" : call.arguments.toString()));


        switch (call.method) {
            case "withoutParams":
                Intent intent = new Intent(mActivity, Flutter2AndroidActivity.class);
                mActivity.startActivity(intent);
                result.success("success");
                break;
            case "withParams":
                if (call.arguments == null) {
                    return;
                }
                Intent intent1 = new Intent(mActivity, Flutter2AndroidActivity.class);
                String text = call.arguments.toString();
                intent1.putExtra("test", text);
                mActivity.startActivity(intent1);
                result.success("success");
                break;
            default:
                result.notImplemented();
                break;
        }
    }

    public void registerWith(BinaryMessenger registrar, Activity activity) {
        methodChannel = new MethodChannel(registrar, CHANNEL_NAME);
        Flutter2AndroidHelp instance = new Flutter2AndroidHelp(activity);
        //setMethodCallHandler在此通道上接收方法调用的回调
        methodChannel.setMethodCallHandler(instance);
    }


}

4.2FlutterActivity 里面注册

package com.supermax.flutter;

import io.flutter.embedding.android.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;

import android.os.Bundle;

public class FlutterActivityPage extends FlutterActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GeneratedPluginRegistrant.registerWith(getFlutterEngine());
        Flutter2AndroidHelp.getInstance().registerWith(getFlutterEngine().getDartExecutor().getBinaryMessenger(),this);

    }
}

4.3main.dart 写代码


import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(_widgetForRoute(window.defaultRouteName));
}

Widget _widgetForRoute(String route) {
  print("111=" + route);
  switch (route) {
    case 'route':
      _toastMessage("111=" + route);
      return MyApp();
    default:
      return Center(
        child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
      );
  }
}

void _toastMessage(String title) {
  Fluttertoast.showToast(
      msg: title,
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.BOTTOM,
      timeInSecForIosWeb: 1,
      backgroundColor: Colors.black45,
      textColor: Colors.white,
      fontSize: 16.0);
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  static MethodChannel _methodChannel= MethodChannel("com.supermax");
  Map<String, String> map = { "Android": "好兄弟,我来了" };

  void _incrementCounter() {
    setState(() {
      _counter++;
      _jumpAndroid();
    });
  }

  _jumpAndroid() async{
    print("来了吗我擦");
    _methodChannel.invokeMethod("withoutParams",map);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

4.4请把MainActivity里面的跳转代码改一下。

   Intent intent = FlutterActivityPage
                        .withNewEngine()
                        .initialRoute("route")
                        .build(MainActivity.this);
                intent.setClass(MainActivity.this, FlutterActivityPage.class);
                startActivity(intent);

PS:里面有个坑,如果不重新指定Activity的话,只会默认去执行FlutterActivity的代码。

标签:FlutterFragment,title,route,FlutterView,Flutter,class,import,Android,flutter
来源: https://blog.csdn.net/qq_37492806/article/details/121105406

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有