android ui flutter,Android项目集成Flutter与相互通讯

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

1.效果展示

16b6923f12fa88409fe05fd101c442d0.gif

2. 集成Flutter

2.1 新建一个Flutter项目,类型选择Flutter Module,路径选择Android项目同级,不要在Android项目中创建。

2.2 在Android项目中的settings.gradle配置flutter module,添加如下代码1

2setBinding(new Binding([gradle: this]))

evaluate(new File(settingsDir.parentFile, 'flutter01/.android/include_flutter.groovy'))

2.3 添加flutter依赖

在app module下的build.gradle中添加flutter依赖,代码如下1

2

3dependencies {

implementation project(':flutter')

}

3.将flutter中的widget显示在Android界面中

3.1 在flutter中写个hello world,代码如下1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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

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

class extends StatelessWidget{

Widget build(BuildContext context) {

return MaterialApp(

home: Scaffold(

appBar: AppBar(title: Text('Flutter')),

body: Text(txt,

style: TextStyle(color: Colors.red, fontSize: 32))

));

}

void sendData() {

methodPlugin.invokeMethod('toast', 'Flutter send data');

print('send data');

}

}

3.2 在Android界面中显示flutter widget

获取到flutter widget并添加到viewgroup中,代码如下1

2

3

4

5

6

7

8

9

10

11

12public class MainActivity extends AppCompatActivity{

private FrameLayout fl;

@Override

protected void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

fl = findViewById(R.id.fl);

FlutterView flutterView = Flutter.createView(this, getLifecycle(), "route01");

fl.addView(flutterView);

}

}

3.3 解决首次加载黑屏问题

我们可以等View绘制完后再显示出来,首先将ViewGroup隐藏设置invisible,注意不能设置为gone,设置为gone后view不会绘制。将flutterView添加到viewGroup后监听第一帧页面的绘制,等第一帧绘制完后,再将viewgroup显示出来,代码如下1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23public class MainActivity extends AppCompatActivity{

private FrameLayout fl;

@Override

protected void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

fl = findViewById(R.id.fl);

FlutterView flutterView = Flutter.createView(this, getLifecycle(), "route01");

fl.addView(flutterView);

showFlutterView(flutterView);

}

private void showFlutterView(FlutterView flutterView){

flutterView.addFirstFrameListener(new FlutterView.FirstFrameListener() {

@Override

public void onFirstFrame(){

flutterView.removeFirstFrameListener(this);

fl.setVisibility(View.VISIBLE);

}

});

}

}

4. 接收flutter发送的消息

Android中通过MethodChannel来接收Flutter的消息,代码如下1

2

3

4

5

6

7new MethodChannel(flutterView, "flutter").setMethodCallHandler((methodCall, result) -> {

switch (methodCall.method) {

case "toast":

fl.post(() -> Toast.makeText(MainActivity.this, methodCall.arguments(), Toast.LENGTH_SHORT).show());

break;

}

});

new MethodChannel(flutterView, "flutter")中的第一个参数为FlutterView,是指消息从哪个View发送的,第二个参数为通道名称,发送消息前需要建立一个通道,在这个通道中发送消息。methodCall.method为消息类型,用于区分不能的消息,methodCall.arguments为消息数据。

flutter也是通过MethodChannel来发送消息,示例中的效果为点击右下角的图标,发送一条消息给android,android接收到消息后,用toast显示,发送消息的代码如下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

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

import 'package:flutter/services.dart';

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

class extends StatelessWidget{

static const methodPlugin = const MethodChannel('flutter');

Widget build(BuildContext context) {

return MaterialApp(

home: Scaffold(

appBar: AppBar(title: Text('Flutter')),

body: Text(txt,

style: TextStyle(color: Colors.red, fontSize: 32)),

floatingActionButton: FloatingActionButton(

onPressed: sendData,

child: Icon(Icons.send),

),

));

}

void sendData() {

methodPlugin.invokeMethod('toast', 'Flutter send data');

}

}

5. Android发送消息给flutter

android中通过EventChannel来给flutter发送消息,代码如下1

2

3

4

5

6

7

8

9

10

11new EventChannel(flutterView, "android").setStreamHandler(new EventChannel.StreamHandler() {

@Override

public void onListen(Object o, EventChannel.EventSink eventSink){

}

@Override

public void onCancel(Object o){

}

});

new EventChannel(flutterView, "android")中的第一个参数为接收消息的对象,第二个参数为通道名称,最后通过EventChannel.EventSink对象来发送消息。可以发送一条成功的消息,eventSink.success("success");也可以发送一条异常消息,eventSink.error("1000", "数据异常", "数据解析异常"),第一个参数为状态码,第二个参数为异常内容,第三个参数的异常详情;也可以发送一个结束信号,eventSink.endOfStream();。

flutter接收消息代码如下1

2

3EventChannel('android')

.receiveBroadcastStream()

.listen(onData, onError: error, onDone: done, cancelOnError: false);

其中listen中的前几个参数均为一个方法,第一个接收成功消息,第二个接收异常消息,第三个接收结束信号,第四个参数是当接收到异常消息后,是否停止消息的接收,当为false时,接收到异常消息后,仍可以继续接收消息。

6. 完整示例代码

activity中的示例代码如下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

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63public class MainActivity extends AppCompatActivity{

private EventChannel.EventSink event;

private FrameLayout fl;

@Override

protected void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

fl = findViewById(R.id.fl);

FlutterView flutterView = Flutter.createView(this, getLifecycle(), "route01");

fl.addView(flutterView);

showFlutterView(flutterView);

receiveFlutterData(flutterView);

new EventChannel(flutterView, "android").setStreamHandler(new EventChannel.StreamHandler() {

@Override

public void onListen(Object o, EventChannel.EventSink eventSink){

event = eventSink;

}

@Override

public void onCancel(Object o){

Log.i("aloe", o.toString());

}

});

}

private void showFlutterView(FlutterView flutterView){

flutterView.addFirstFrameListener(new FlutterView.FirstFrameListener() {

@Override

public void onFirstFrame(){

flutterView.removeFirstFrameListener(this);

fl.setVisibility(View.VISIBLE);

}

});

}

private void receiveFlutterData(FlutterView flutterView){

new MethodChannel(flutterView, "flutter").setMethodCallHandler((methodCall, result) -> {

switch (methodCall.method) {

case "toast":

fl.post(() -> Toast.makeText(MainActivity.this, methodCall.arguments(), Toast.LENGTH_SHORT).show());

break;

}

});

}

public void onClick(View view){

switch (view.getId()) {

case R.id.btn_success:

event.success("Android send data");

break;

case R.id.btn_fail:

event.error("1000", "数据异常", "数据解析异常");

break;

case R.id.btn_finish:

event.endOfStream();

break;

default:

break;

}

}

}

flutter中的示例代码如下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

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

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

import 'package:flutter/services.dart';

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

class extends StatelessWidget{

static const methodPlugin = const MethodChannel('flutter');

Widget build(BuildContext context) {

return MaterialApp(

home: Scaffold(

appBar: AppBar(title: Text('Flutter')),

body: MyView(),

floatingActionButton: FloatingActionButton(

onPressed: sendData,

child: Icon(Icons.send),

),

));

}

void sendData() {

methodPlugin.invokeMethod('toast', 'Flutter send data');

}

}

class MyView extends StatefulWidget{

State createState() {

return MyState();

}

}

class MyState extends State{

static const eventPlugin = const EventChannel('android');

String txt = 'Hello Flutter';

void initState() {

super.initState();

eventPlugin

.receiveBroadcastStream()

.listen(onData, onError: error, onDone: done, cancelOnError: false);

}

@override

Widget build(BuildContext context) {

return Text(txt,

style: TextStyle(color: Colors.red, fontSize: 32));

}

void updateTxt(String text) {

setState(() {

txt = text;

});

}

void onData(Object data) {

print(data);

updateTxt(data);

}

void error(Object error) {

PlatformException e = error;

updateTxt('code: ${e.code}, msg: ${e.message}, detail: ${e.details}');

}

void done() {

updateTxt('Hello Flutter');

}

}

android发送消息,flutter用Text来展示,flutter发送消息,android用toast来提示,其它布局代码不是很复杂,在此不作展示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值