Flutter跨平台APP開發學習目錄

入門:

功能:

flutter_signin_button
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();
}
}
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_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(); //在執行完驗證操作後,自動關閉
在Google Drive API設定及串接的部份,記得要產生自己的ID和Secret。
作者有提供影片可以參考
我自己修改的版本:可以用WebView登入,這樣就不會使用預設瀏覽器登入,跳出APP畫面了需要和secureStorage.dart搭配
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
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(
.....
),
進度指示器
LinearProgressIndicator
CircularProgressIndicator
GridView.count():決定APP畫面要幾個Col
GridView.extent():決定APP中child的最大寬度
[Flutter] Layout - GridView and ListViewFlutter滾動控件篇>GridView、CustomScrollView
[方案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
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))
參考資料# 使用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');
例如:拍照前取得拍照權限,但是拍完後因為沒有讀取/寫入SD卡的權限,導致要重新再拍照,才能保存的問題。
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);
在VS Code透過F5來啟動AVD的時候出現以上錯誤解法:https://github.com/flutter/flutter/issues/29589#issuecomment-475954731刪除.vscode資料夾即可
注意pubspec.yaml是不是有哪一行多了額外的空格,也會導致該問題產生
Widget转化为Image截屏操作Flutter实现区域(组件)截图Creating raw image from Widget or Canvas
How to set landscape orientation mode for flutter app?How to change screen orientation in Flutter
[方案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

專案:

推薦閱讀:

Written by

Machine Learning / Deep Learning / Python / Flutter cakeresume.com/yanwei-liu

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store