话不多说,先上效果图:是不是很炫酷~
源码地址:github.com/taxze6/flut…(希望给点点star⭐)
本文分析重点:
使用插件:
#状态管理 + 路由管理
get: 4.2.0
# 本地存储 + 图片缓存
shared_preferences: ^2.0.6
cached_network_image: ^3.0.0
复制代码
mvp的全称为Model-View-Presenter,Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理。
举个例子:
使用Getx进行封装:
数据存放:
class SplashModel {
late String Background;
late String SplashText;
late String SplashButtonText;
BuildContext? context = Get.context;
///初始化数据
SplashModel() {
Background = "images/splash/Splash.png";
SplashText = "Rehoming and adoption. You find each other.";
SplashButtonText = "Let's Start";
}
}
复制代码
在controller中定义SplashModel,使用数据:
class SplashController extends GetxController {
final SplashModel splashModelState = SplashModel();
}
复制代码
在view中使用控制器:
final controller = Get.put(SplashController());
final state = Get.find<SplashController>().splashModelState;
//使用:
Text(state.SplashText)
复制代码
这里就需要使用全局信息配置了,然后使用shared_preferences本地持久化
简单的定义用户信息:
UserLoginResponseModel userLoginResponseModelFromJson(String str) => UserLoginResponseModel.fromJson(json.decode(str));
String userLoginResponseModelToJson(UserLoginResponseModel data) => json.encode(data.toJson());
class UserLoginResponseModel {
UserLoginResponseModel({
this.token,
this.name,
this.id,
});
String? token;
String? name;
int? id;
factory UserLoginResponseModel.fromJson(Map<String, dynamic> json) => UserLoginResponseModel(
token: json["token"],
name: json["name"],
id: json["id"],
);
Map<String, dynamic> toJson() => {
"token": token,
"name": name,
"id": id,
};
}
复制代码
全局配置怎么去做呢?
定义一个Global文件
class Global{}
复制代码
在这个文件中我们可以进行app的全局配置
例如:
/// 用户配置
static UserLoginResponseModel? profile = UserLoginResponseModel(token: null);
///是否是第一次打开
static bool isFirstOpen = false;
///是否登录
static bool isOfflineLogin = false;
复制代码
重点来啦!定义一个init方法用于初始化:
static Future init() async{
// 运行初始
WidgetsFlutterBinding.ensureInitialized();
//本地存储初始化
await LoacalStorage.init();
// 读取离线用户信息
var _profileJSON = LoacalStorage().getJSON(STORAGE_USER_PROFILE_KEY);
if (_profileJSON != null) {
profile = UserLoginResponseModel.fromJson(_profileJSON);
isOfflineLogin = true;
}
// android 状态栏为透明的沉浸
if (Platform.isAndroid) {
SystemUiOverlayStyle systemUiOverlayStyle = const SystemUiOverlayStyle(statusBarColor: Colors.transparent);
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
}
isFirstOpen = !LoacalStorage().getBool(STORAGE_DEVICE_ALREADY_OPEN_KEY);
if (isFirstOpen) {
LoacalStorage().setBool(STORAGE_DEVICE_ALREADY_OPEN_KEY, true);
}
}
复制代码
之后我们就可以在main文件中初始化这配置文件
void main() => Global.init().then((value) => runApp(MyApp()));
复制代码
然后我们就可以进行判断啦:
Obx(() => Scaffold(
body: controller.isloadWelcomePage.isTrue
? SplashPage() //引导页
: Global.isOfflineLogin
? HomePage() //首页
: LoginPage(), //登录页
)
复制代码
在上方我们已经进行了SplashModel的数据定义
那么让我们来看看动画吧,因为时MVP架构,所以我们关于AnimationController的处理要放到controller中,我们使controller继承于SingleGetTickerProviderMixin。
class SplashController extends GetxController
with SingleGetTickerProviderMixin {
AnimationController? animationController;
}
复制代码
然后再初始化动画(记得销毁哦):
@override
void onInit() {
super.onInit();
animationController = AnimationController(
duration: const Duration(milliseconds: 1500), vsync: this);
animationController!.forward();
}
@override
void onClose() {
// TODO: implement onClose
super.onClose();
animationController!.dispose();
}
复制代码
按钮动画(view):
Widget Splash_Button(BuildContext context) => ScaleTransition(
//动画处理
scale: Tween<double>(begin: 0, end: 1).animate(CurvedAnimation(
parent: controller.animationController!,
curve: const Interval(0.3, 0.6, curve: Curves.fastOutSlowIn),
)),
child: GestureDetector(
onTap: () {
controller.getTo();
},
child: Container(
//按钮
),
),
);
复制代码
就是这么的简单,如果觉得不够详细可以自己下拉源码查看~
关于引导页的背景,我们这里有个优化的点,提前缓存图片: 在controller中onInit中缓存:
@override
void onInit() {
super.onInit();
_precacheImage(splashModelState.Background, splashModelState.context!);
}
void _precacheImage(String imageUrl, BuildContext context) {
precacheImage(AssetImage(imageUrl), context);
}
复制代码
上文说到没有分析的原因是因为本人遇到一件很重要的事,一件在绝望中寻找希望的事,也许没有了周末,没有了假期,不能在编写Flutter系列的文章,不能和小伙伴们谈论技术,但是,人生嘛总要有舍有得~
最后送所有正在努力的大家一句话:你不一定逆风翻盘,但一定要向阳而生。
我是阿T,山水有相逢,我们江湖见。(我们很快再见~)
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。