1.Androidstudio 获取dart支持才会出现 下图,才可以单独运行
2.需要 flutter pub get
3.Android Studio 中使用 FlutterJsonBeanFactory 插件
注意点:需要保证该 Android Studio 窗口下是一个完整的Flutter项目(窗口下有且仅有一个Flutter项目,不能在文件夹内),否则会提示
最终代码中识别的代码
4.仿微信图库选择
名称 | likes | 是否维护 | url | 缺点 |
---|---|---|---|---|
image-picker | 4635 | 是 | https://pub.flutter-io.cn/packages/image_picker | 太过简单,多选需要长按,不能限制数量 |
wechat_camera_picker | 420 | 是 | https://pub.dev/packages/wechat_camera_picker | 和crm项目包冲突,解决半天,无法搞定,影响性很大 |
images_picker | 140 | 是 | https://pub.flutter-io.cn/packages/images_picker | 和crm项目包冲突,解决半天,无法搞定,影响性很大 |
-
image-picker
https://pub.flutter-io.cn/packages/image_picker
太过简单,多选需要长按,不能限制数量 -
wechat_camera_picker
https://pub.dev/packages/wechat_camera_picker
minSdkVersion 21满足项目需求,和crm项目包冲突,解决半天,无法搞定,影响性很大
-
images_picker
https://pub.flutter-io.cn/packages/images_picker
满足项目需求,和crm项目包冲突,解决半天,无法搞定,影响性很大
5.系统权限
permission_handler
https://pub.flutter-io.cn/packages/permission_handler
//获取拍照(camera、写)和相册权限(读)
import 'package:permission_handler/permission_handler.dart';
Future<void> _initData() async {
Map<Permission, PermissionStatus> statuses = await [
Permission.photos,
Permission.camera,
].request();
if (statuses.values.first.isGranted) { }
}
6.安全距离
bottom: MediaQuery.of(context).padding.bottom
7.ListView嵌套GridView
由于 GridView 和 ListView 都是可以滚动的组件,所以嵌套的时候要注意把里面的组件改为不可滚动组件。
重要属性:
shrinkWrap: true, //解决无限高度问题
physics:NeverScrollableScrollPhysics(), //禁用滑动事件
8.get
https://pub.dev/packages/get
它集高性能状态管理、智能依赖注入和路由管理于一体,既快速又实用。
class FeedbackController extends GetxController {
openGallery(int index, int num) async {
update();
}
}
GetBuilder<FeedbackController>(builder: (_){
//更新页面
}
final controller = Get.put(FeedbackController());
///输入框监听
TextField(
onChanged: (text) {
controller
..content = text
..update();
},
)
eg:
import 'package:bruno/bruno.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get_state_manager/src/simple/get_controllers.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../../../common/global_app_config.dart';
import '../../../../common/utils/keyboard_util.dart';
class FeedbackController extends GetxController {
int value = 0;
List<String> photoEntity = [];
int maxNum = 3; //图片最大选择数
///反馈内容
String content = '';
int contentMaxNum = 300; //反馈内容最大字数
/// 获取当前展示个数,用来判断是否显示加号图片
int getShowNum() {
int showNum = 0;
if (photoEntity.length >= 3) {
showNum = maxNum;
} else {
showNum = photoEntity.length + 1;
}
return showNum;
}
/// 打开相册
/// [index] 索引
openGallery(int index, int num) async {
if (photoEntity.length >= 3) {
print("超出了3张");
return;
}
if (index == photoEntity.length) {
Map<Permission, PermissionStatus> statuses = await [
Permission.photos,
Permission.camera,
].request();
if (statuses.values.first.isGranted) {
await GlobalConfig.getInstance()
.syncImagesData(maxNum - photoEntity.length)
.then((map) {
var list = map?["path"] as List<Object?>;
for (var element in list) {
photoEntity.add(element.toString());
}
update();
});
}
}
}
//调用反馈接口
requestFeedback(BuildContext context) {
if (value == 0) {
BrnToast.show("请选择问题类型", context);
return;
}
if (content.isEmpty) {
BrnToast.show("请填写反馈内容", context);
return;
}
KeyboardUtils.hideKeyboard(context);
}
}
9.flutter 传值给Android
//Flutter
Future<Map<Object?, Object?>?> syncImagesData(int num) async {
// 原生响应 getGlobalData 方法
return await _methodChannel.invokeMethod<Map<Object?,Object?>?>("getImagesData",{"num": num});
}
//Android
var num: Int = call.argument<Int>("num") ?:0
10.flutter 键盘出现时候导致固定底部的按钮被顶上来
Scaffold(
resizeToAvoidBottomInset: false,
)
12.需要重启的场景
- 加入图片
- JsonConvert 中加入新的类
13.json 中data为数组格式的解析方式
class JsonConvert {
static final Map<String, JsonConvertFunction> _convertFuncMap = {
(FeedBackTypeModelEntity).toString(): FeedBackTypeModelEntity.fromJson,
(FeedBackModelEntity).toString(): FeedBackModelEntity.fromJson,
(MessageControl).toString(): MessageControl.fromJson,
(UsedCarOrderModelEntity).toString(): UsedCarOrderModelEntity.fromJson,
(UsedCarOrderStatusCountEntity).toString(): UsedCarOrderStatusCountEntity.fromJson,
};
}
/// 反馈类型数据
var getFeedbackTypeResult = ValueNotifier<LoadState?>(null);
void getFeedbackType() {
getFeedbackTypeResult.value = Loading();
Network.getInstance().getList<FeedBackTypeModelEntity>(
"api/app/feedback/type", (result) {
print("111111111${result.data}");
getFeedbackTypeResult.value = Loaded(result.data);
}, (error) {
LoadError(error.code, error.message);
});
}
###14.返回到主页
跳转入口加入
Navigator.pushAndRemoveUntil(context,
MaterialPageRoute(builder: (context) => FeedBackResultPage()),
(Route<dynamic> route) => false);
14.flutter抓包
client.findProxy = (uri) {
//proxy all request to localhost:8888
return 'PROXY 172.20.28.248:8888';
};
15.返回
返回上一层
Navigator.pop(context);
返回到原生
SystemNavigator.pop();