Flutter 中的 Intents
可以看看这篇 Flutter
页面跳转,携带参数的页面跳转的使用和说明点击跳转
在Android中,Intent 用来做Activity 之间的跳转,又或者用来发送广播,传递消息。那么,在Flutter中,它有什么替代方式呢?
如果需要在Flutter中进行页面切换,可以使用路由,具体代码如下:
import 'package:flutter/material.dart';
//void main() => runApp(MaterialApp(home: DemoApp()));
void main() {
runApp(MaterialApp(
home: DemoApp(), // becomes the route named '/'
routes: <String, WidgetBuilder>{
'/a': (BuildContext context) => MyPage(title: "page A"),
'/b': (BuildContext context) => MyPage(title: 'page B'),
'/c': (BuildContext context) => MyPage(title: 'page C'),
},
));
}
class MyPage extends StatelessWidget {
final String title;
MyPage({this.title});
Widget build(BuildContext context) {
return Center(child: Text(title));
}
}
class DemoApp extends StatelessWidget {
// Widget build(BuildContext context) => Scaffold(body: Signature());
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("DemoApp"),
),
floatingActionButton: FloatingActionButton(
onPressed: () => _toPageA(context),
tooltip: 'Update Text',
child: Icon(Icons.update),
),
);
}
void _toPageA(BuildContext context) {
Navigator.of(context).pushNamed("/a");
}
}
首先自定义了
routes
然后定义了按钮点击事件,使其跳转到pageA
。
routes 定义多个页面并省略 home 的写法
在 Flutter中,编写一个页面,必须提供 home
并 return
一个 Widght
来显示页面,但是在 MaterialApp
中,通过编写 routes
是可以忽略掉 home
的,就像下面的例子:
import 'package:flutter/material.dart';
void main() {
runApp(new FlutterReduxApp());
}
class FlutterReduxApp extends StatelessWidget {
FlutterReduxApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return new MaterialApp(routes: {
"/": (context) {
// store.state.platformLocale = Localizations.localeOf(context);
return MyPage();
},
"/b": (context) {
///通过 Localizations.override 包裹一层,
return MyPage();
},
"/c": (context) {
return MyPage();
},
});
}
}
class MyPage extends StatelessWidget {
final String title;
MyPage({this.title});
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("this is Push Page")),
body: new Center(
child: new RaisedButton(
child: new Text("点击返回"),
onPressed: () => Navigator.of(context).pop("this is result text"),
color: Colors.blue,
highlightColor: Colors.lightBlue,
),
),
);
}
}
在routes 中,必须提供
/
这样的一个根目录,否则是会报错的,就像这样
class FlutterReduxApp extends StatelessWidget {
FlutterReduxApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return new MaterialApp(routes: {
"/a": (context) {
// store.state.platformLocale = Localizations.localeOf(context);
return MyPage();
},
"/b": (context) {
///通过 Localizations.override 包裹一层,
return MyPage();
},
"/c": (context) {
return MyPage();
},
});
}
}
错误:
I/flutter (20735): 'package:flutter/src/widgets/app.dart': Failed assertion: line 178 pos 10: 'builder != null ||
I/flutter (20735): home != null ||
I/flutter (20735): routes.containsKey(Navigator.defaultRouteName) ||
I/flutter (20735): onGenerateRoute != null ||
I/flutter (20735): onUnknownRoute != null'
Flutter中如何在dart 和 java 文件之间传递数据?
某些数据需要在java端处理之后,交由界面显示,这时候就需要flutter 和java 之间的交互了
首先,在 java 文件Activity
的 onCreate
中定义如下方法:
package com.example.fluttertestapp;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;
import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity {
private final String sharedText = "this is shared text";
Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
handler = new Handler();
// handler.postDelayed(new Runnable() {
// @Override
// public void run() {
//
// Toast.makeText(MainActivity.this, String.format("start main thread:%d", 1600), Toast.LENGTH_SHORT).show();
// }
// }, 1600);
new MethodChannel(getFlutterView(), "app.channel.shared.data")
.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if (methodCall.method.contentEquals("getSharedText")) {
result.success(sharedText);
}
}
});
}
}
然后在 main.dart
中定义
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(SampleApp());
}
class SampleApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sample Shared App Handler',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SampleAppPage(),
);
}
}
class SampleAppPage extends StatefulWidget {
SampleAppPage({Key key}) : super(key: key);
@override
_SampleAppPageState createState() => _SampleAppPageState();
}
class _SampleAppPageState extends State<SampleAppPage> {
static const platform = const MethodChannel('app.channel.shared.data');
String dataShared = "No data";
@override
void initState() {
super.initState();
getSharedText();
}
@override
Widget build(BuildContext context) {
return Scaffold(body: Center(child: Text(dataShared)));
}
getSharedText() async {
var sharedData = await platform.invokeMethod("getSharedText");
if (sharedData != null) {
setState(() {
dataShared = sharedData;
});
}
}
}
运行程序就可正确的获取到 shareText
了
在看官方demo中,发现了
await
字眼,说明应该是延时调用,所以,尝试在activity
中也延时返回数据,发现,并不会导致程序阻塞,但是会导致数据获取失败,在实际测试中,当延迟在1600
的时候,有时成功获取shareText
,有时则失败。具体代码如下:
package com.example.fluttertestapp;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;
import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity {
private final String sharedText = "this is shared text";
Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
new MethodChannel(getFlutterView(), "app.channel.shared.data")
.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if (methodCall.method.contentEquals("getSharedText")) {
result.success(sharedText);
}
}
});
Toast.makeText(MainActivity.this, String.format("start main thread:%d", 1600), Toast.LENGTH_SHORT).show();
}
}, 1600);
}
}
为了防止调用方法的失败,最好不要在主线程中执行延时线程去返回方法。
Flutter 中如何跳转到另一个页面后,获取返回值?
在Android原生编程中,可以使用
startActivityForResult
来获取另一个页面的返回值,那么,在Flutter
中呢
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: DemoApp(), // becomes the route named '/'
routes: <String, WidgetBuilder>{
'/a': (BuildContext context) {
debugPrint("select route A");
// Navigator.of(context).pop("this is result text");
return MyPage(title: "page A");
}
},
));
}
class MyPage extends StatelessWidget {
final String title;
MyPage({this.title});
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("this is Push Page")),
body: new Center(
child: new RaisedButton(
child: new Text("点击返回"),
onPressed: () => Navigator.of(context).pop("this is result text"),
color: Colors.blue,
highlightColor: Colors.lightBlue,
),
),
);
}
}
class DemoApp extends StatelessWidget {
// Widget build(BuildContext context) => Scaffold(body: Signature());
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("DemoApp"),
),
floatingActionButton: FloatingActionButton(
onPressed: () => _toPageA(context),
tooltip: 'Update Text',
child: Icon(Icons.update),
),
);
}
Future _toPageA(BuildContext context) {
debugPrint("this is debug info");
// Navigator.of(context).pushNamed("/a");
Future result = Navigator.of(context).pushNamed("/a");
result.then((value) {
debugPrint(value);
});
}
}
首先,通过 Navigator.of(context).pushNamed("/a")
跳转到另一个页面,然后使用 Future.then
获取返回,这个返回值是在另一个页面中,通过Navigator.of(context).pop("this is result text")
传递而来。
网友评论