flutter项目初始化
- 0、flutter 官方插件网址
- 1、flutter项目环境配置
- 2、flutter数据本地存储(shared_preferences)
- 3、GetX 中的数据响应式配合本地存储使用
- 4、Dio 封装使用详解
- 5、EasyLoading的使用
- 6、缓存 keep-alive使用(除了Tabbar,其它的页面、组件都可以使用)
- 7、缓存 tabbar(补充6的缓存 - bottomNavigationBar)
- 8、tabbar的使用
- 9、GetX中的路由管理
- 10、判断组件是否被卸载掉
- 11、flutter中静态图片的配置
- 12、字体使用
- 13、GetX中controller、binding管理状态
- 14、GetX中 defaultDialog、snackbar、bottomSheet(使用Shape设置了圆角) 使用
- 15、GetX 国际化
- 16、系统自带的dialog框
0、flutter 官方插件网址
flutter官方链接
数据模型转换
注意:使用 flutter 的时候一定要把数据放在父组件中(主要是指Dio数据请求),往子组件传展示
1、flutter项目环境配置
待做
2、flutter数据本地存储(shared_preferences)
1、dependencies:
shared_preferences: ^2.2.2
2、utils 包里面创建文件:
shared_preferences.dart
import 'dart:convert';import 'package:shared_preferences/shared_preferences.dart';class JSpUtil {JSpUtil._internal();factory JSpUtil() => _instance;static final JSpUtil _instance = JSpUtil._internal();static late SharedPreferences _preferences;static Future<JSpUtil> getInstance() async {_preferences = await SharedPreferences.getInstance();return _instance;}/// 通用设置持久化数据static setLocalStorage<T>(String key, T value) {String type = value.runtimeType.toString();switch (type) {case "String":_preferences.setString(key, value as String);break;case "int":_preferences.setInt(key, value as int);break;case "bool":_preferences.setBool(key, value as bool);break;case "double":_preferences.setDouble(key, value as double);break;case "List<String>":_preferences.setStringList(key, value as List<String>);break;}}/// 获取持久化数据static dynamic getLocalStorage<T>(String key) {dynamic value = _preferences.get(key);if (value.runtimeType.toString() == "String") {if (_isJson(value)) {return json.decode(value);}}return value;}/// 获取持久化数据中所有存入的keystatic Set<String> getKeys() {return _preferences.getKeys();}/// 获取持久化数据中是否包含某个keystatic bool containsKey(String key) {return _preferences.containsKey(key);}/// 删除持久化数据中某个keystatic Future<bool> remove(String key) async {return await _preferences.remove(key);}/// 清除所有持久化数据static Future<bool> clear() async {return await _preferences.clear();}/// 重新加载所有数据,仅重载运行时static Future<void> reload() async {return await _preferences.reload();}/// 判断是否是json字符串static _isJson(String value) {try {const JsonDecoder().convert(value);return true;} catch(e) {return false;}}
}
3、入口函数加上两句话,不然报错
void main() async {// 下面两句是持久化数据用的WidgetsFlutterBinding.ensureInitialized();await JSpUtil.getInstance();runApp(const ApplicationApp());
}
4、使用
// 1、取值
JSpUtil.getLocalStorage('token');// 2、存值
JSpUtil.setLocalStorage("token", "需要存的值");
3、GetX 中的数据响应式配合本地存储使用
1、创建 store 仓库
// 根目录下创建 store/store.dart 文件// store.dart 文件里面
import 'package:get/get.dart';
import 'package:hook_up_rant/utils/shared_preferences.dart';class StoreIndex {// 变量(首先从本地储存取,没有的话就定义一个) static var token = JSpUtil.getLocalStorage("token").toString() == "null" ? "".obs : (JSpUtil.getLocalStorage("token").toString()).obs;static void updateToken(String str) {// 改变状态token.value = str;// 同时持久化到本地存储JSpUtil.setLocalStorage("token", str);}
}
2、使用
// 存储数据并且持久化
StoreIndex.updateToken('存储的数据');// 取出数据
StoreIndex.token.value;
// 在页面上渲染需要使用 Obx(() => Container()) 包裹, 使数据具有响应式
4、Dio 封装使用详解
1、安装 Dio
dio: ^4.0.0
2、封装 Dio
// 在 utils 包里面创建 http 目录
// 然后创建四个文件// 1、 http_request.dart 核心文件
import 'package:dio/dio.dart';
import 'package:hook_up_rant/utils/http/http_interceptor.dart';
import 'package:hook_up_rant/utils/http/http_options.dart';// http 请求单例类
class HttpRequest {// 工厂构造方法factory HttpRequest() => _instance;// 初始化一个单例实例static final HttpRequest _instance = HttpRequest._internal();// dio 实例Dio? dio;// 内部构造方法HttpRequest._internal() {if (dio == null) {// BaseOptions、Options、RequestOptions 都可以配置参数,优先级别依次递增,且可以根据优先级别覆盖参数BaseOptions baseOptions = BaseOptions(baseUrl: HttpOptions.BASE_URL,connectTimeout: HttpOptions.CONNECT_TIMEOUT,receiveTimeout: HttpOptions.RECEIVE_TIMEOUT,headers: {},);// 没有实例 则创建之dio = Dio(baseOptions);// 添加拦截器dio!.interceptors.add(HttpInterceptor());// 打印日志// dio!.interceptors.add(LogInterceptor(responseBody: true));}}/// 初始化公共属性 如果需要覆盖原配置项 就调用它////// [baseUrl] 地址前缀/// [connectTimeout] 连接超时赶时间/// [receiveTimeout] 接收超时赶时间/// [headers] 请求头/// [interceptors] 基础拦截器// void init({ String? baseUrl, int? connectTimeout, int? receiveTimeout, Map<String, dynamic>? headers, List<Interceptor>? interceptors }) {// print("许潇111 --- $baseUrl -- $connectTimeout --- $receiveTimeout --- $headers -- $interceptors");// dio!.options.baseUrl = baseUrl ?? "";// dio!.options.connectTimeout = connectTimeout ?? 10000;// dio!.options.receiveTimeout = receiveTimeout ?? 10000;// dio!.options.headers = headers;// if (interceptors != null && interceptors.isNotEmpty) {// dio!.interceptors.addAll(interceptors);// }// }/// 设置请求头void setHeaders(Map<String, dynamic> headers) {dio!.options.headers.addAll(headers);}final CancelToken _cancelToken = CancelToken();/** 取消请求** 同一个cancel token 可以用于多个请求* 当一个cancel token取消时,所有使用该cancel token的请求都会被取消。* 所以参数可选*/void cancelRequests({CancelToken? token}) {token ?? _cancelToken.cancel("cancelled");}/// GETFuture get(String path, {Map<String, dynamic>? params, Options? options, CancelToken? cancelToken, ProgressCallback? onReceiveProgress}) async {Response response = await dio!.get(path,queryParameters: params,options: options,cancelToken: cancelToken ?? _cancelToken,onReceiveProgress: onReceiveProgress);return response.data;}/// POSTFuture post(String path, { Map<String, dynamic>? params, Options? options, CancelToken? cancelToken, ProgressCallback? onSendProgress, ProgressCallback? onReceiveProgress}) async {Response response = await dio!.post(path,data: params,options: options,cancelToken: cancelToken ?? _cancelToken,onSendProgress: onSendProgress,onReceiveProgress: onReceiveProgress);return response.data;}/// 文件上传Future postFormData(String path, { Map<String, dynamic>? params,