可以在线看黄的网站-可以免费在线看黄的网站-可以免费看污视频的网站-可以免费看毛片的网站-欧美电影免费看大全-欧美电影免费

用Flutter寫一個畢設app的經驗(flutter 設計稿)

Flutter我也不是很了解,但自從我接觸了這門跨端技術開發之后,我是深深地喜歡上了它的UI、它的交互和動畫。很多人會吐槽它的無限嵌套,這是它有所不足的地方。喜歡一項技術,就像喜歡一個人一樣,看到Ta的優點的同時也能包容它的缺點。

我認識一位才女,她在今年的畢業設計中,設計了一款app的UI。我當時有個想法,把她的畢設開發出一個app。后面聯系的機會也比較少,各自忙各自的去啦!直到2021.08.23號,我跟她拿了設計稿,并通過新技術開始了一個周的開發經歷。

看到設計稿,我第一感覺是:在設計和配色方面讓人聯想到文化和古風

應用介紹:運用扁平風插畫的形式來表現苗族特有的民族特征,文化和樂器,以最新潮的方式推廣給每一位用戶,讓《苗韻》成為一款趣味性的科普APP。

用Flutter寫一個畢設app的經驗(flutter 設計稿)用Flutter寫一個畢設app的經驗(flutter 設計稿)用Flutter寫一個畢設app的經驗(flutter 設計稿)用Flutter寫一個畢設app的經驗(flutter 設計稿)

應用開發后的交互視頻

經驗分享:

1.實現引導頁

用Flutter寫一個畢設app的經驗(flutter 設計稿)

引導頁面

兩種選擇,可以選擇pageview自行搭建自己的引導頁;

stack(children:[ Positioned.fill( // 根據需求構建自己的應到也 child: PageView.builder() ) ] // 指示器內容 buildDot())

另外一種選擇是可以選擇使用插件:這個插件構建出來的引導頁也不錯

intro_views_flutter

2.實現組件突出效果

用Flutter寫一個畢設app的經驗(flutter 設計稿)

像這種卡片上移的效果,對于flutter來說不太好實現,而且實現之后還需要注意層級會遮擋。

兩種實現方式:

使用stack布局,有一個缺點,如果內容是長列表,那會導致里面的內容無法正常的滑動,比較適合小卡片布局。比如上圖中向外突出的樂器。

stack(children:[ position( top:-30, //關鍵代碼在這里 ), ])

使用 配合transform: Matrix4.translationValues(0.0, -100.0, 0.0),配合ClipPath

ClipPath( //定義裁切路徑 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.音樂播放的實現

用Flutter寫一個畢設app的經驗(flutter 設計稿)

在使用這個插件的時候,我在編譯的時候遇到了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,遇到的問題絕不是上面的這一點點。大家有不懂得多多交流。

相關新聞

聯系我們
聯系我們
在線咨詢
分享本頁
返回頂部