Flutter跨平台APP開發學習目錄

Yanwei Liu
16 min readSep 2, 2019

--

入門:

FlutLab.io — Flutter IDE online

使用Visual Studio Code開發Flutter時的快捷鍵

flutter_roadmap

awesome-flutter

編寫Flutter APP的語言:Dart

Flutter跨平台APP開發:環境建立

Flutter常用指令

Flutter:新增懸浮按鈕、文字風格、圖片、常見按鈕、ICON、Containers、Padding Rows、Columns、Expanded Widgets

Flutter:打包Android APP

Flutter:關於pubspec.yaml

Flutter CheatSheet

Flutter:Reponsive Design

功能:

Flutter:更改APP Bar顏色

Flutter:如何將AppBar標題的文字置中?

Flutter:更改APP背景顏色

Flutter:更改ICON

Flutter:暫存圖片

Flutter:聊天機器人APP - 使用Dialogflow

Flutter:透過Bootstrap框架進行APP開發

Flutte:FFmpeg Tool

Flutter:登入按鈕

flutter_signin_button

Flutter:使用Firebase登入Google帳戶

Flutter + Firebase(一) : 設定環境
Flutter + Firebase(二) : RealTimeDB CRUD
Flutter + Firebase(三) : JSON 序列化與Firebase實作
如果每次開啟APP,都會跳出登入Google帳戶的畫面,該怎麼辦?我們可以設定一個bool,來去判斷使用者是否登入。if 登入成功,直接進APP (已登入的狀態)
else 進入登入畫面 (沒登入的狀態)
class CheckAuth extends StatefulWidget {
@override
_CheckAuthState createState() => new _CheckAuthState();
}

class _CheckAuthState extends State<CheckAuth> {
bool isLoggedIn;
@override
void initState() {
isLoggedIn = false;
FirebaseAuth.instance.currentUser().then((user) => user != null
? setState(() {
isLoggedIn = true;
})
: null);

super.initState();
}

@override
Widget build(BuildContext context) {
return isLoggedIn ? new Home() : new LoginScreen();
}
}

Flutter:將圖片上傳到Firebase上

import 'dart:io';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:uuid/uuid.dart';
import 'package:uuid/uuid_util.dart';
File _image, cropped,imageFile;
var uuid = new Uuid();
void _startUpload() async {

// 使用Mac地址作為檔案名稱
var email = userEmail.replaceAll(RegExp('@gmail.com'), '');
var imageName =
email+"_"+_platformVersion.replaceAll(':', '-')+"_"+uuid.v4(options: {'rng': UuidUtil.cryptoRNG});
// 在Firebase建立路徑給去背後的圖片保存
final ref = FirebaseStorage.instance.ref().child('images/$imageName.jpg');
// url變數為上傳至Firebase後的圖片連結
var url;
// putfile() 用來將圖片上傳到Firebase上
await ref.putFile(File(imageData)).onComplete.then((value) async {
url = await ref.getDownloadURL();
print("圖片名稱:" + imageName + ".jpg");
print("圖片連結:" + url);
print("成功上傳到Firebase Storage");
});
}

Flutter:使用WebView進行Google登入驗證時,出現403 disallowed_useragent錯誤

使用flutter_webview_plugin 0.3.11套件首先要解決err_cleartext_not_permitted錯誤接著要建立一個假的User-Agentconst kAndroidUserAgent =
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Mobile Safari/537.36';
flutterWebViewPlugin.launch(
url,
userAgent: kAndroidUserAgent,
);
flutterWebViewPlugin.close(); //在執行完驗證操作後,自動關閉

Flutter:整合Google Drive上傳檔案

在Google Drive API設定及串接的部份,記得要產生自己的ID和Secret。
作者有提供影片可以參考
我自己修改的版本:可以用WebView登入,這樣就不會使用預設瀏覽器登入,跳出APP畫面了需要和secureStorage.dart搭配

Flutter:FB登入整合

Flutter:取得設備Mac Address

Flutter:新增splash screen

Step1.編輯launch_background.xml<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<item>
<bitmap
android:gravity="fill"
android:mipMap="true"
android:src="@mipmap/splash" />

</item>
</layer-list>
Step2.在Flutter_project_name\android\app\src\main\res當中的每個mipmap-XXdpi資料夾裡面,都放入splash.jpg的檔案https://medium.com/@dushanthimadhushika3/a-simple-flutter-splash-screen-part-1-746d5df9c5b5

Flutter:詢問使用者是否退出APP的AlertDialog(WillPopScope Widget)

class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => showDialog(
context: context,
builder: (context) =>AlertDialog(title: Text('你確定要退出嗎?'), actions: <Widget>[
RaisedButton(child: Text('退出'), onPressed: () => Navigator.of(context).pop(true)),
RaisedButton(child: Text('取消'), onPressed: () => Navigator.of(context).pop(false)),
]
)
),
child: Scaffold(
.....
),

Flutter:底部導航列換頁(Bottom Navigation)

Flutter:前往新視窗並且返回

Flutter:降低圖片造成APP檔案過大之問題

Flutter:Pull to Refresh

使用Github Actions持續部署Flutter到Google Play

Flutter:進度條功能

進度指示器
LinearProgressIndicator
CircularProgressIndicator

Flutter:GridView、ListView

GridView.count():決定APP畫面要幾個Col
GridView.extent():決定APP中child的最大寬度
[Flutter] Layout - GridView and ListViewFlutter滾動控件篇>GridView、CustomScrollView

Flutter:解決寫的function要透過onPressed才能執行的辦法

[方案1]Flutter: Run method on Widget build complete根據上文所介紹的,after_layout套件,我們可以在進入該screen後,立刻執行我們的function,這樣就不會遇到說,一定要再用button才能執行function了。原本的方式:
APP首頁點擊拍照按鈕->拍照頁面->按下拍照Button->進入系統相機
透過after_layout套件,我們可以變成以下的流程,節省不少時間
APP首頁點擊拍照按鈕->進入系統相機
程式碼如下class HomeScreenState extends State<HomeScreen> with AfterLayoutMixin<HomeScreen> {@override
Widget build(BuildContext context) {
return new Scaffold(body: new Container(color: Colors.red));
}
@override
void afterFirstLayout(BuildContext context) {
showHelloWorld();
}
void showHelloWorld() {
//put your content here....
}
}
[方案2]使用initState()或Future.delayed()的原生執行,不過若函數內部有context參數,似乎就不太能用。這部份未來遇到再研究看看,先使用方案1的可行方案https://stackoverflow.com/questions/52059024/show-dialog-on-widget/52062540#52062540

Flutter:一定要hot reload後圖片或內容才會正常顯示

Do not use rootBundle to open files that were not packed with the app via pubspec.yaml. Open them with File class.# 將local image轉成ImageProvider型態(用於PDF Printing時)
image: FileImage(File(widget.imagePath))

Flutter:如何分享檔案(以圖片為例)

參考資料# 使用esys_flutter_share套件
# 原本的官方範例使用rootBundle去載入圖片
# 然而,若要載入local的圖片,會產生路徑錯誤的問題
# 改用File載入圖片、readAsBytes轉換格式
# 用Uint8List.fromList將List轉成Uint8List
# 最後透過Share.file分享檔案
File Image2share = File(widget.imagePath);
List<int> bytes = await Image2share.readAsBytes();
Uint8List ubytes = Uint8List.fromList(bytes);
await Share.file('分享圖片', fileName, ubytes, 'image/jpg');

Flutter:首次啟動APP顯示的對話框(只顯示於首次啟動)

Flutter:在首次啟動就處理APP權限問題,避免後續BUG產生

例如:拍照前取得拍照權限,但是拍完後因為沒有讀取/寫入SD卡的權限,導致要重新再拍照,才能保存的問題。

Flutter:將從任何地方(相機拍攝、網路、Cache)取得的照片保存到本地

import 'package:image_picker/image_picker.dart';
import 'package:gallery_saver/gallery_saver.dart';
String albumName ='Media';GallerySaver.saveImage(imageFile.path, albumName: albumName);// 範例1 用裝置相機來拍攝圖片及影片:
ImagePicker.pickImage(source: ImageSource.camera).then((File recordedImage){GallerySaver.saveImage(recordedImage.path)}
ImagePicker.pickVideo(source: ImageSource.camera).then((File recordedVideo){GallerySaver.saveVideo(recordedVideo.path)}// 範例2 從網路下載圖片及影片:
String path ="https://www.XXX.com/abc.jpg';
GallerySaver.saveImage(path);
String path ="https://www.XXX.com/abc.mp4';
GallerySaver.saveVideo(path);

Error: Error when reading ‘bin/main.dart’: The system cannot find the path specified.

在VS Code透過F5來啟動AVD的時候出現以上錯誤解法:https://github.com/flutter/flutter/issues/29589#issuecomment-475954731刪除.vscode資料夾即可

使用flutter pub get指令時,卡住

注意pubspec.yaml是不是有哪一行多了額外的空格,也會導致該問題產生

針對已經排版好的Widget內容進行截圖(RepaintBoundary)

Widget转化为Image截屏操作Flutter实现区域(组件)截图Creating raw image from Widget or Canvas

強制APP方向隨著手機方向變更(portrait、landscape)

How to set landscape orientation mode for flutter app?How to change screen orientation in Flutter

如何更改Flutter的專案package name

[方案1]Android更改build.gradle、iOS更改Info.plist[方案2]使用以下指令重新建立project
flutter create --org com.yourdomain appname
[推薦:方案3]
Modifying the bundle identifier, package name & app display name in a Flutter app

Flutter Route路由學習筆記

專案:

Flutter計時器APP

Flutter個人簡介APP

Flutter網路圖片APP

Flutter:Remove.bg 去背APP

如何建立一個基於Flutter的物件偵測APP(TensorFlow lite+ Tiny YOLOv2)

How To Use TensorFlow lite in Flutter?

How To Build an Cross Platform ML APP with Flutter and TensorFlow Lite using Google Teachable Machine

Building a Cross-Platform Image Classifier with Flutter and TensorFlow Lite

推薦閱讀:

--

--

No responses yet