- APP神圣官网 > 热点资讯 > 正文
Flutter我也不是很了解,但自从我接触了这门跨端技术开发之后,我是深深地喜欢上了它的UI、它的交互和动画很多人会吐槽它的无限嵌套,这是它有所不足的地方喜欢一项技术,就像喜欢一个人一样,看到Ta的优点的同时也能包容它的缺点我认识一位才女,她在今年的毕业设计中,设计了一款app的UI我当时有个想法,把她的毕设开发出一个app后面联系的机会也比较少,各自忙各自的去啦
直到2021.08.23号,我跟她拿了设计稿,并通过新技术开始了一个周的开发经历视频加载中...看到设计稿,我第一感觉是:在设计和配色方面让人联想到文化和古风应用介绍:运用扁平风插画的形式来表现苗族特有的民族特征,文化和乐器,以最新潮的方式推广给每一位用户,让《苗韵》成为一款趣味性的科普APP应用开发后的交互视频视频加载中...经验分享:1.实现引导页引导页面两种选择,可以选择pageview自行搭建自己的引导页;stack(children:[ Positioned.fill( // 根据需求构建自己的应到也 child: PageView.builder()) ] // 指示器内容 buildDot())
另外一种选择是可以选择使用插件:这个插件构建出来的引导页也不错intro_views_flutter
2.实现组件突出效果像这种卡片上移的效果,对于flutter来说不太好实现,而且实现之后还需要注意层级会遮挡两种实现方式:使用stack布局,有一个缺点,如果内容是长列表,那会导致里面的内容无法正常的滑动,比较适合小卡片布局比如上图中向外突出的乐器stack(children:[ position( top:-30, //关键代码在这里 ), ])
使用 配合transform: Matrix4.translationValues(0.0, -100.0, 0.0),配合ClipPathClipPath( //定义裁切路径 clipper: BackgroundClipper(), child: Container( ), )
BackgroundClipper 用于裁剪上移后,容器下面部分的内容4.实现全局加载动画和单个加载动画插件推荐:# loading动画 flutter_spinkit: ^5.0.0
全局加载模态 import 'package:flutter/material.dart';import 'package:flutter_miaoyun/utills/color_utils.dart';import 'package:flutter_spinkit/flutter_spinkit.dart';class Loading extends StatelessWidget { static void show(BuildContext context) { showDialog( barrierDismissible: true, context: context, builder: (ctx) => Theme( data: Theme.of(ctx).copyWith(dialogBackgroundColor: Colors.transparent), child: Loading(), ), ); } static void dismiss(context) { Navigator.pop(context); } @override Widget build(BuildContext context) { return Container( color: Colors.transparent, child: Center( child: Container( decoration: BoxDecoration( color: Colors.transparent, borderRadius: BorderRadius.circular(5), ), width: 60, height: 60, alignment: Alignment.center, child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ SpinKitCubeGrid( color: gColor("#C8AD6B"), size: 46.0, ) ], ), ), ), ); }}// 调用 Loading.show() 隐藏 Loading.dismiss()
单个加载动画,可参考插件的demo 自行选用5.实现点击菜单移动到对应的内容区域插件:# 跳转到对应的页面 scroll_to_index: ^2.0.0
6.音乐播放的实现在使用这个插件的时候,我在编译的时候遇到了kotlin版本不匹配问题,我的解决方案是看插件的example使用的是哪个版本,然后再Android Stadio 中更新kotlin到对应的版本之后就完美解决# 音频播放 audioplayers: ^0.19.1
音频播放的逻辑大概的分享一下我是将audio的实例对象初始化后存到controller中,这样就可以在多个页面对音乐进行控制7.制作闪屏页插件推荐flutter_native_splash配置dev_dependencies: flutter_test: sdk: flutter flutter_native_splash: ^1.2.0flutter_native_splash: # color: "#42a5f5" #image: assets/splash/icon.png background_image: assets/guides/splash.png # color_dark: "#042a49" #image_dark: assets/splash/icon.png background_image_dark: assets/guides/splash.png android: true ios: true web: true fullscreen: true使用:三步走flutter clean flutter pub getflutter pub run flutter_native_splash:create
8.本地存储插件推荐shared_preferences
封装import 'dart:convert';import 'package:shared_preferences/shared_preferences.dart';class SPUtils { // 静态实例 static SharedPreferences _sharedPreferences; // 应用启动时需要调用 // 初始化 static Future<bool> init() async { _sharedPreferences = await SharedPreferences.getInstance(); return true; } // 清除数据 static void remove(String key) async { if (_sharedPreferences.containsKey(key)) { _sharedPreferences.remove(key); } } // 异步保存数据类型 static Future save(String key, dynamic value) async { if (value is String) { _sharedPreferences.setString(key, value); } else if (value is bool) { _sharedPreferences.setBool(key, value); } else if (value is double) { _sharedPreferences.setDouble(key, value); } else if (value is int) { _sharedPreferences.setInt(key, value); } else if (value is List<String>) { _sharedPreferences.setStringList(key, value); } } // 异步读取数据 static Future<String> getString(String key) async { return _sharedPreferences.getString(key); } static Future<int> getInt(String key) async { return _sharedPreferences.getInt(key); } static Future<bool> getBool(String key) async { return _sharedPreferences.getBool(key); } static Future<double> getDouble(String key) async { return _sharedPreferences.getDouble(key); } // 保存自定义对象 static Future saveObject(String key, dynamic value) async { // 通过json 将Object对象编译成String类型保存 _sharedPreferences.setString(key, json.encode(value)); } // 获取自定义对象 static dynamic getObject(String key) { String _data = _sharedPreferences.getString(key); return (_data == null || _data.isEmpty) ? null : json.decode(_data); } // 保存类表数据 static Future<bool> putObjectList(String key, List<Object> list) { List<String> _dataList = list?.map((value) { return json.encode(value); })?.toList(); return _sharedPreferences.setStringList(key, _dataList); } // 获取对象集合数据 // 返回的是List <Map<String ,dynamic>>类型 static List<Map> getObjectList(String key) { if (_sharedPreferences == null) return null; List<String> dataList = _sharedPreferences.getStringList(key); return dataList?.map((value) { Map _dataMap = json.decode(value); return _dataMap; })?.toList(); }}
以上是在开发过程中觉得不错,可以分享给flutter爱好者的相关知识也是我在开发过程中遇到的一些技术难点淡然有很多要开发一个app,遇到的问题绝不是上面的这一点点大家有不懂得多多交流
联系我们
在线咨询:
0 评论