flutter 性能优化方案1.遥遥领先 Flutter3.0 性能优化系列|一文教你完全掌握内存优化和dark虚拟机 (内存泄露) - 简书
flutter 图片优化之MemoryImage 如何在 Flutter 中使用MemoryImage【Flutter专题】-云社区-华为云
flutter 实用开发前言 · Flutter核心技术与实战 · 看云
flutter实用技巧网址十五、全面理解State与Provider · GitBook
flutter 插件网站模块插件
flutter 组件大全控件大全 pdf 控件继承关系图 | Flutter | 老孟
pub.dev
flutter响应式布局ToluUI Flutter TolyUI 框架#01 | 响应式布局#使用篇-腾讯云开发者社区-腾讯云
日期的处理https://www.cnblogs.com/wyhlightstar/p/11059942.html
Flutter组件(Widget)的局部刷新方式https://www.jianshu.com/p/7765d8605864
flutter 避免空异常--no-sound-null-safety
flutter 设定版本号
1.可以在yaml里面设置version但这种格式必须是1.0.0+1这种,1.0.0代表versionName,1表示versionCode
2.可以在app/build.gradle里面的defaultConfig设置,这里面versionName更灵活
flutter适应多版本打包flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi --no-sound-null-safety
StreamSubscription数据回调 https://www.jianshu.com/p/5ffb4c9030d6
1.TextField 与Row的关系
TextFiled不能直接放在Row中,需要用Expend包裹
TextField调整边框颜色enabledBorder未选中,focusedBorder选中
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.orange),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
2.如ListView.builder这类的循环界面,想给其循环之前或之后再加内容
可以使用Column->Expanded->ListView.builder的方式就可以在column中再添加内容
3.输入框键盘问题,看Flutter中解决输入框(TextField)被键盘遮挡问题 - 简书
4.每个控件尽量用container包住
5.当container的 alignment不起作用时,可以使用Align控件的alignment然后再包住container
6.布局适配使用ScreenUtil进行适配
7.double bottom = MediaQuery.of(context).viewInsets.bottom;可以计算距离底部的距离。
8.final EdgeInsets edgeInsets = MediaQuery.of(context).padding;edgeInsets.top为顶部导航栏的高度。
9.调用图片的方式
①Image(image: AssetImage("images/find_more_friend_addfriend_icon.png"),);②Image.asset("images/suo.png",);
③在Container中decoration: BoxDecoration(image: DecorationImage(image: AssetImage(returnIcon),fit: BoxFit.contain)),添加底图
10.setState会重建当前的widget
11.当使用到异步处理UI FutureBuilder时,应当避免其获取数据后直接在当前class继续写页面,应当另起一个class写之后的widget,然后在futureBuilder中调用。
12.三目运算符比ifelse适用很多
13.线条或者间隔间距可以用sizeBox去做
14.异步任务请求流程
/**
* 请求接口获取数据
*/
Future<Response> getData() async {
String url = "http://v.juhe.cn/toutiao/index";
String key = "4c52313fc9247e5b4176aed5ddd56ad7";
String type = "keji";
print("开始请求数据");
Response response =
await Dio().get(url, queryParameters: {"type": type, "key": key});
print("请求完成");
return response;
}
main() {
getData().then((result) {
print("接口返回的数据是:${result}");
}).whenComplete((){
print("异步任务处理完成");
}).catchError((){
print("出现异常了");
});
print("我是在请求数据后面的代码呦!");
}
15.setState()的代码不能是异步的
16.客户端开发,合理的做法是容器嵌套,而不是拼凑样式,并且不要随意设置容器尺寸,尽量让容器按照元素或者内容的大小自动撑开或者缩小,这样就不会出问题,设置尺寸一般只存在于最小单位,几乎不会影响布局的时候才可以设置,例如用户头像可以设置固定的宽高。
17.方法.then((r)=>{})
18.post/get请求,有body时,要用这种形式写
var apiUrl = Uri.parse("http://192.168.10.1:7777/Api/Interface/Execute");
var res = await http.post(apiUrl,body: json.encode({"":""}), headers: {'Content-Type': 'application/json'}, );
19.对于异步方法,返回值为Future<>的不能直接取值,必须用.then去取,而且这种也可以防止数据没加载完就去执行组件
Future<R> _getState()async{
R r = await Service.post(AppConfig.hdfwdz);
return r;
}
_getState().then((r) => {}
20.flutter list 类型传给后端
必须将必须将list类型tostring,后端接收还是以list类型接收
data['signImage'] = this.signImage.toString();
21.flutter map类型传给后端
可以先将map类型进行编码
data['signImage'] = json.encode(this.signImage);
然后在在java端以string类型接收,在对其进行转换为map类型
Map signImage2 = JSONObject.parseObject(signImage);
22.要多个text的样式拼接
Container(
padding: EdgeInsets.only(bottom: 10.h,right: 40.w,left: 50.w),
alignment: Alignment.centerLeft,
child:
//SizedBox(width: 50.w,),
RichText(
textScaleFactor: MediaQuery.of(context).textScaleFactor,
maxLines: 2,
overflow: TextOverflow.ellipsis,
text: TextSpan(
children: [
TextSpan(
text: "医生简介:",
style: TextStyle(
color: HexToColor.hexToColor(AppConfig.rendeInterfaceDto.getZsmcztys() != null ? AppConfig.rendeInterfaceDto.getZsmcztys() : "#FFFFFF" ),
fontSize: 20.h,
decoration: TextDecoration.none //底线样式
)
),
TextSpan(
text: "认真负责,能吃苦工作勤奋,认真负责,能吃苦耐劳,尽职能吃苦工作勤奋,认真负责,能吃苦耐劳,尽职尽责,认真负责,能吃苦工作勤奋,认真负责,能吃苦耐劳,尽尽责,认真负责,能吃苦工作勤奋,认真负责,能吃苦耐劳,尽职尽责",
style: TextStyle(
color: HexToColor.hexToColor(AppConfig.rendeInterfaceDto.getZsmcztys() != null ? AppConfig.rendeInterfaceDto.getZsmcztys() : "#FFFFFF" ),
fontSize: 20.h,
decoration: TextDecoration.none //底线样式
)
)
]
),
),
),
23.要text显示这样可以使用让rou高度一致的控件
IntrinsicHeight(
child: Row(
children: [
Container(
alignment: Alignment.topLeft,
child: Text(
"医生简介:",
style: TextStyle(
color: HexToColor.hexToColor(AppConfig.rendeInterfaceDto.getNotesTitleColor() != null ? AppConfig.rendeInterfaceDto.getNotesTitleColor() : "#FFFFFF" ),
fontSize: 20.h,
decoration: TextDecoration.none //底线样式
)
),
),
Expanded(
child: Text(
doctorDto.description,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: HexToColor.hexToColor(AppConfig.rendeInterfaceDto.getNotesColor() != null ? AppConfig.rendeInterfaceDto.getNotesColor() : "#FFFFFF" ),
fontSize: 20.h,
decoration: TextDecoration.none //底线样式 color: HexToColor.hexToColor(AppConfig.rendeInterfaceDto.getNotesColor() != null ? AppConfig.rendeInterfaceDto.getNotesColor() : "#FFFFFF" ),
)
),
)
],
)
),
24.在container中让居中后,没有居中的原因,可能为子控件的Row或Column没有设置mainAxisAlignment
30.ClipRRect会和Container的阴影产生冲突导致阴影不显示
31.想要让Expanded下的container可以设置最大高度,就要把Expanded改成其父类Flexible并将属性fit: FlexFit.loose,就可以设置最大高度了(因为Expanded默认的为fit:FlexFit.tight)
32.网络图片加载失败加载本地图片的方法
Image.network(
AppConfig.rendeInterfaceDto.getYsxxbjtp(),
height: double.infinity,width: double.infinity,fit: BoxFit.fill,
errorBuilder: (ctx,err,stackTrace) => Image.asset(
'images/zy_hp.png',//默认显示图片
height: double.infinity,width: double.infinity,fit: BoxFit.fill,
)
),
32.要熟练使用??与?.,并了解两者之间的不同
A??B
如果 A 等于 null,那么 A??B 为 B
如果 A 不等于 null,那么 A??B 为 A
A?.B
如果 A 等于 null,那么 A?.B 为 null
如果 A 不等于 null,那么 A?.B 等价于 A.B
33.对默认导航栏操作
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);//隐藏状态栏,底部按钮栏
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom]);//隐藏状态栏,保留底部按钮栏
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values);//显示状态栏、底部按钮栏
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( //设置状态栏透明
statusBarColor: Colors.transparent,
));
34.await 和isolated
async和await:
对于普通的任务,使用async和await可实现异步处理任务,而async的处理方式并非使用的是多线程,而是依然在UI线程中处理任务,是在同一个线程上的并发操作。
对于比较繁重的处理任务,可使用compute来开启新isolate,来处理任务。
isolate:
是类似于线程,但不共享内存的独立的worker。是一个独立的dart程序执行环境。
对于每一个flutter应用,当应用被启动时都会有一个默认的isolate,称为root isolate。我们自己的代码默认情况下都在这个isolate中执行。
35.Flutter 在release模式下显示灰屏 debug 正常显示