创建flutter项目指定代码
flutter create -i objc -a java flutter_name
-i 代表iOS
-a 代表android
//获取手机物理分辨率
final physicalWidth = window.physicalSize.width;
final physicalHeight = window.physicalSize.height;
//获取dpr (像素比)
final dpr = window.devicePixelRatio;
//宽度 高度
final width = physicalWidth / dpr;
final height = physicalHeight / dpr;
print("physicalWidth== ${physicalWidth}");//physicalWidth== 750.0
print("physicalHeight== ${physicalHeight}");//physicalHeight== 1334.0
print("dpr== ${dpr}");//dpr== 2.0
print("width== ${width}");//width== 375.0
print("height== ${height}");//height== 667.0
WindowPadding padding = window.padding;
print("padding.top== ${padding.top/dpr}");
print("padding.bottom== ${padding.bottom/dpr}");
print("padding.left== ${padding.left/dpr}");
print("padding.right== ${padding.right/dpr}");
//获取屏幕宽高
final size = MediaQuery.of(context).size;
final width = size.width;
final height = size.height;
EdgeInsets padding = MediaQuery.of(context).padding;
print("padding.top== ${padding.top}");
print("padding.bottom== ${padding.bottom}");
print("padding.left== ${padding.left}");
print("padding.right== ${padding.right}");
1
FittedBox适配缩放功能(子视图会根据父视图做缩放,子视图布局(父视图)显示不下的话会缩小子视图,反之放大子视图充满父视图)
2
Future getStr() {
return;//这里直接return的话 接收的返回值是 null 走then的逻辑
}
3
Stack
Stack(
children: <Widget>[
new Align(
alignment: Alignment(0, -1),
child: Image.network("imageUrl"),
),
new Positioned(
left: 10,
right: 10,
top: 10,
height: 30,
child: Container(
alignment: Alignment.center,
color: Color.fromARGB(100, 255, 0, 0),
child: Text("subTitle"),
),
),
],
),
4
ListView 嵌套经典错误: haseSize错误
解决方法1:属性 shrinkWrap: true,根据子Widget计算所需空间
解决方法2:包裹Expanded
Expanded(
child:ListView(
children:<Widget>{
}
)
)
5
加载json
// static Map<String, Map<String, String>> _localizeValues = {};
//
// Future loadJson() async {
// // 1.加载json文件
// final jsonString = await rootBundle.loadString("assets/json/i18n.json");
//
// // 2.对json进行解析
// Map<String, dynamic> map = json.decode(jsonString);
//
// _localizeValues = map.map((key, value) {
// //在这里 将dynamic转成Map<String, String>
// return MapEntry(key, value.cast<String, String>());
// });
// }
6
国际化插件:Android Studio中添加插件:flutter Intl
7
左滑返回手势
WillPopScope(
onWillPop: () async {
print("onWillPop Action ---");
},
)
8
Offstage
显示隐藏
9
Opacity
透明度
10 请求权限。打开设置
image_picker: ^0.6.7 #相册选择图片
multi_image_picker: ^4.6.7 #相册选择图片
permission_handler: ^5.0.1 #请求权限。打开设置
if (Platform.isIOS) {
final status = await Permission.photos.status;
if (status == PermissionStatus.denied) {
var hasOpened = openAppSettings();
return;
}
final status1 = await Permission.camera.status;
if (status1 == PermissionStatus.denied) {
var hasOpened = openAppSettings();
return;
}
}else if (Platform.isAndroid){
final status = await Permission.camera.status;
if (status == PermissionStatus.permanentlyDenied) {
var hasOpened = openAppSettings();
return;
}
}
Map<Permission, PermissionStatus> statuses =
await (Platform.isIOS ? [
Permission.photos,
Permission.camera,
] : [
Permission.camera,
]).request();
if (Platform.isIOS && statuses[Permission.photos].isGranted && statuses[Permission.camera].isGranted){
_showImagesPicker();
} else if (Platform.isAndroid && statuses[Permission.camera].isGranted) {
_showImagesPicker();
} else {
AppToast.toastMessage('相册权限未打开');
}
11
数组 字符串 互转
List list = List();
list.add("A");
list.add("B");
print("list== ${list}");//list== [A, B]
String listStr = list.join(",");
print("listStr== ${listStr}");//listStr== A,B
List StrToList = listStr.split(",");
print("StrToList== ${StrToList}");//StrToList== [A, B]
12
builder执行完 再执行 该方法
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
Future.delayed(Duration(seconds: 1), () {
});
});
13
/*
pop返回到根路由
Navigator.of(context).popUntil((route) => route.isFirst);
Screen1, Screen2, Screen3, Screen4
当前在Screen4页面,点击回到Screen1,连带着Screen2,Screen3也一起退出
Navigator.of(context).popUntil(ModalRoute.withName('/screen1'));
Screen1, Screen2
//当前在Screen2页面,点击退出当前页面,并push到Screen3
Navigator.of(context).popAndPushNamed('/screen3');
//正常的push路由跳转
Navigator.of(context).pushNamed('/screen2')
Screen1, Screen2, Screen3
//当前在Screen2页面,点击push到Screen3,并remove掉screen2页面
//1.1这是普通的跳转
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context){
return Screen3();
}), ModalRoute.withName('/screen1'));
//1.2这是路由的跳转
Navigator.of(context).pushNamedAndRemoveUntil('/screen3', ModalRoute.withName('/screen1'));
现在是 Screen1, Screen3,
//当前在Screen1页面,点击push到Screen2,并remove掉screen1页面
Navigator.of(context).pushReplacementNamed('/screen2');
*/
14
iOS样式
CupertinoSwitch
截屏2020-07-28 15.52.15.png
android样式
Switch
截屏2020-07-28 15.52.26.png
15
PopupMenuButton下拉列表
PopupMenuButton(
onSelected: (value) {
print("123value====== ${value}");
},
onCanceled: () {
print("123456===");
},
initialValue: "1",
itemBuilder: (BuildContext context) {
return <PopupMenuItem<String>>[
new PopupMenuItem(
value: "1",
child: new Text("11111111", style: TextStyle(color: Colors.red))),
new PopupMenuItem(
value: "2",
child: new Text("22222", style: TextStyle(color: Colors.grey)))
];
},
child: Text("点击显示下啦列表"),
)
16
状态栏颜色
主要用到的是appbar中的brightness属性,
Brightness.dark 白色
Brightness.light 黑色
appBar: AppBar(
title: Text('标题'),
brightness: Brightness.dark,
elevation: 1.0,
)
没有导航栏的场景
@override
Widget build(BuildContext context) {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light,
child: Material(
child:Scaffold()
)
);
}
网友评论