关于Flutter 的安装如果有什么疑问可以看一下上一篇文章,如果有什么疑问可以留言。
疑问1.如何解决客户端在不同的地方调用不同的Flutter界面。
看下面的Flutter 代码和注释应该很容易理解
import 'package:flutter/material.dart';
import 'dart:ui';
import 'package:my_flutter/WidgetListPage.dart';//导入头文件
// window.defaultRouteName 是由 OC 代码中FlutterViewController setInitialRoute 传入。
void main() => runApp(_widgetForRoute(window.defaultRouteName));
//根据不同的名称来显示不同的界面
Widget _widgetForRoute(String route) {
switch (route) {
case 'myApp':
return new MyApp();
case 'WidgetList':
return new WidgetListPage();
default:
return Center(
child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
);
}
}
疑问2:Flutter 和 Native通信。
在实际场景中Flutter 多时候要与 Native进行通信,我带入2个场景做解释。
场景1:(Flutter 主动和Native通信)Flutter 初始化从Native 获取网络请求后刷新界面。(解释一下,由于原Native 实现了从服务器获取数据的容错、token处理等,所以这里考虑从Native获取数据后刷新Flutter 界面)
Flutter代码块1 (创建通知)
// 创建一个给native的channel (类似iOS的通知)注意:类属性
static const methodChannel = const MethodChannel('com.pages.your/native_get');
Flutter代码块2 (发送通知并等待返回数据-异步)
// 获取首页数据
Future<Null> _fetchWorkSpaceData() async {
dynamic result;// dynamic 为动态类型 类似 OC 中 id
try {
result = await methodChannel.invokeMethod('fetchWorkSpaceData');
} on PlatformException {
result = "error";
}
print(result);
if (result is Map) {
//调用此方法会刷新 Widget build(BuildContext context)
setState(() {
Map mapData = result;//result 为动态类型这里不能直接传参, 还没有发现动态类型强转,所以这里转一下
//MAP 类型转模型 推荐转义链接(https://javiercbk.github.io/json_to_dart/ (JSON 转Dart Model. 注意:转好的Model 要经过处理然后进行使用)
)
JLBWorkSpaceModel model = JLBWorkSpaceModel.fromJson(mapData);
this.workSpaceData.clear();
this.workSpaceData.addAll(this.internalData(model));
});
}
}
Flutter代码块3
//初始化 请求数据
void initState(){
super.initState();
_fetchWorkSpaceData();
}
OC 代码块
// 要与dart中一致(随便定)
NSString *channelName = @"com.pages.your/native_get";
FlutterMethodChannel *messageChannel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:self];
[messageChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
// call.method 获取 flutter 给回到的方法名,要匹配到 channelName 对应的多个 发送方法名,一般需要判断区分
// call.arguments 获取到 flutter 给到的参数,(比如跳转到另一个页面所需要参数)
// result 是给flutter的回调, 该回调只能使用一次
if ([call.method isEqualToString:@"fetchWorkSpaceData"]) {
//获取数据的Api
[[JLBWorkSpaceManager shared] fetchModel:^(JLBWorkSpaceModel *model) {
if (result) {
//转为 NSDictionary 后直接返回给Flutter,Flutter收到会是一个Map类型
result([model mj_keyValues]);
}
}];
}
}];
场景2:(native 主动和Flutter 通信)主界面切换用户身份,界面进行数据刷新。
(这只是简单的实现)
oc代码块1 (创建通知)
//界面初始化时 创建Channel Name 记得和Dart一致
self.sendChannel = [FlutterBasicMessageChannel messageChannelWithName:@"samples.flutter.io/message" binaryMessenger:self];
oc 代码块2 (发送通知)
//在切换身份的地方加上发送刷新通知代码
if (self.sendChannel) {
[self.sendChannel sendMessage:@"refresh"];
}
Flutter代码块1(创建通知)
// An highlighted block
static const messageChannel = const BasicMessageChannel('samples.flutter.io/message', StandardMessageCodec());
Flutter代码块2(接收通知)
void initState(){
super.initState();
messageChannel.setMessageHandler((message) async {
if (message is String) {
if(message == "refresh"){
_fetchWorkSpaceData();
}
}
return '返回Native端的数据';//如果这里有特殊处理再返回进行处理 OC 有代理接收
});
}
疑问3:Flutter 中 界面的border实现(开发中遇到的坑)。
类型下图的边框实现
代码如下
Container(
margin: EdgeInsets.fromLTRB(12, 8, 12, 0),
decoration: new BoxDecoration(
border: new Border.all(width:1.0, color: Color(0xFFEDEDED)),
borderRadius: const BorderRadius.all(const Radius.circular(1.0)),
)
),
疑问4:Flutter 图片资源获取
在 Flutter 文件夹中找到 pubspec.yaml 把你所有的文件资源声明好如下
然后在同目录下完成资源添加
然后在Flutter 中使用
Image.asset("images/shense.png")
疑问5: Flutter 图片展示充满方式类似OC 的UIViewContentMode
Image.asset("images/shense.png",
fit: BoxFit.cover,//类似 OC UIViewContentMode
)
疑问6:Flutter Color 的使用 16 进制 “#EDEDED”
Flutter 代码
Color(0xFFEDEDED)
疑问7:Flutter 中text 使用
Text(
"这是一条很长很长的文字111111111111111111111111111111",
overflow: TextOverflow.ellipsis,//展示不下后缀点点……省略
maxLines: 1,//行数设置
style: TextStyle(fontSize: 13,color: Color(0xFF2D2D2D)),),//字体大小、颜色等设置
)
疑问8:Flutter Widget 使用
看完以上疑问基本上就可以写Flutter 简单的界面了,如果有更多的以为比如内存暴涨等问题可以看一下 闲鱼对Flutter 使用写的文章https://www.jianshu.com/u/cf5c0e4b1111