跳到主要內容

Flutter: TextButton and build fail issue

為了達成寫一套code就能在兩個平台跑的目標,一直不斷練習寫flutter.

然而寫flutter前一定要有android 或ios 開發的基礎,

不然會遇到很多困難.

例如我就遇到android studio內的build.gradle設定問題,跟android X有關.

編譯時一直出現紅字,

Caused by: java.lang.ClassNotFoundException: Didn't find class “xxxx.xxx.xxx” on path: DexPathList error 

查看

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="$APP_DOMAIN"> 

<application android:name="io.flutter.app.FlutterApplication" android:label="$APP_NAME" android:icon="@mipmap/ic_launcher"> <activity android:name=".MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <meta-data android:name="io.flutter.app.android.SplashScreenUntilFirstFrame" android:value="true" />

似乎是full package name issue, 把.MainActivity 改成 full package name type: (請查看自己的app package name)

但後來發現這樣也是不行的. 單獨開啟android子目錄來build android可以通過,但回到上層flutter top level build就會失敗.(上層會成功才可以,因為一次build all platform: android/ios/web)

trouble 2: 

error: Keep getting "Unsupported Android Plugin version: 3.5.3" error on build 

上面這問題也是很難解.一般android app開發都是用最新版的,不會有問題,但在flutter上並不是這樣,flutter不支援最新的版本,所以要選擇穩定的版本.

感覺目前flutter還是有很多坑. 我是使用目前這版本.(希望未來改版能改進一堆的build錯誤的問題)

Flutter is already up to date on channel stable
Flutter 2.2.2 • channel stable • https://github.com/flutter/flutter.git
Framework • revision d79295af24 (8 days ago) • 2021-06-11 08:56:01 -0700
Engine • revision 91c9fc8fe0
Tools • Dart 2.13.3

solution: 確保以下設定,記住最新的版本不一定會比較好,反而有可能會出現錯誤,我目前可以build flutter app at android emulator的設定,特別須注意紅字的部分.

top level: build.gradle

buildscript {
ext.kotlin_version = '1.3.20'
repositories {
google()
jcenter()
}

dependencies {
classpath 'com.android.tools.build:gradle:4.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

app 內的build.gradle:

android {
compileSdkVersion 30

lintOptions {
disable 'InvalidPackage'
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com...."
minSdkVersion 16
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
} ...} 

gradle-wrapper.properties

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

gradle.properties:

org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true

 其他沒寫的部分建議參考flutter 自動產生的hello world 範本去設定.

光處理上面這些問題就花了我三個小時,好險我對android studio很熟,之前寫android 原生app就遇到過此問題,所以才能馬上解掉該compile不過的問題. 不然怎麼跑都無法跑成功的.一般人的話早放棄了.

我相信ios開發也是同樣的,開發者也要對xcode有所了解,

只有app上架後,才知道你會遇到的一些困難是什麼.所以不能說學習flutter後,android studio或xcode都放棄不用了,都要有所涉略才對.


1.上面這個範例(點圖可看到動畫)是研究BottomNavigationBar.跟textButton的事件處理.

BottomNavigationBar example可參考: https://github.com/heruijun/FlutterFrom0To1/tree/master/chapter3/flutter_bottomnav

首先flutter跟android或ios有一點不一樣的地方是Layout.

android 可以用拖拉的方式來設計 Layout. ios可以用storyboard的方式.

但是flutter目前v2的版本好像還不可以.必須要用寫程式的方式寫在.dart內.

必須要了解Column, Row, Container, children, child 等Layout屬性的用法.

這樣很不好用.

 

2. flutter內元件沒有id, 不像android 或ios. 

flutter 是用controller的方式.可是這樣就要多建立一個變數.

其他人是這樣做.https://stackoverflow.com/questions/50056003/updating-text-field-in-flutter-on-button-click

例如:

new TextButton(
onPressed: () {
//action
setState(() {
do_something();
});
},
child: Text(
(buttontext1.length == 0
? "Event Button A"
: buttontext1), //title
textAlign: TextAlign.center, //aligment
style: TextStyle(fontSize: 24.0),
),
),

var count = 0; 

var buttontext1 = "";

void do_something() {
count++;
buttontext1 = "clicked Event Button A: time $count";
}

也就是說我目前還不能用元件id的方法來直接修改元件顯示的內容,必須要設定一個間接的變數.

實在有點麻煩.

controller詳細說明可參考: https://flutter.dev/docs/cookbook/forms/text-field-changes

對一開始設計flutter的android/ios 開發者來說,實在會有點不習慣.

ps: android/ios可用元件id的方式直接改元件的設定或值,不須設定間接變數,方便許多.

但是,可能對於其他很多人來說,這樣可能才是他們熟習的方法.

習慣用MVVM的方式,不直接去call UI,反而是先設定好值,再用批次更新UI的setState()方式.

所以我覺得換個領域,很多觀念都會有所不同.


 

 

 

 

 

 

 

留言

這個網誌中的熱門文章

最爛的銀行服務-玉山銀行

今天寫信給玉山銀行,問他說能不能給予我免費跨行轉帳次數, 我是他們大客戶....常常需要轉帳跟提款.發現這樣被扣手續費很不划算. 玉山銀行的atm又很少見. 但是得到的回應是這樣: 看完這信,有回答等於沒回答,當下我就決定要轉到其他家銀行了, 只是有點麻煩,股票帳戶,外幣帳戶,黃金存摺帳戶... 玉山銀行在我家附近連一台提款機都沒有,每次都要借台新銀行或中信銀行的atm. 把錢放在這裡實在不方便,不斷被扣轉帳手續費跟提款手續費. 你看台新銀行richard給我五次免費額度. 使用其他家例如合作金庫與兆豐銀行都有台灣pay可以免手續費. 玉山銀行???? 今天開始要開始廢棄玉山銀行了.... 而且看這回信後,我也覺得玉山銀行很爛,自己不建atm,又不給客戶免費跨行提款次數,叫我跑大老遠自己搜尋ATM. 建議大家他的股票: 玉山 金控 ( 2884 ) 也不要買, 股價一定會慢慢下跌的,看他們家的服務讓客戶一個一個跑掉,就知道了 . 未來不是有很多純網銀出來嗎? 他們都會給予更多免費跨行轉帳次數. 感覺未來這種服務不佳的銀行都準備被淘汰吧. 對於app設計師來說: 這種回答也是最不佳的. 我們要對user友善點,使用者反應app會當機,有問題時, 回答要能解決他們的問題. 千萬不能像玉山銀行客服人員這樣回答. 使用者都是很厲害的,他發現你沒鳥他,明天開始就刪除app了. PS:後來去辦了兆豐銀行.行員說只要辦個數位帳戶就有10次跨行提款...而且已經有一般非數位帳戶也可再申請一個數位的. 相比玉山銀行還限制如果有玉山帳戶者再申請數位帳號也沒有跨行轉帳提款優惠,玉山真的好差... 除此之外,台新銀行也給我各5次免費跨行轉帳+提款次數 真的好好..(以上都不用薪轉戶,一般人都有資格可以申請) 有了15次轉帳跟跨行提款免費,就不用到處找ATM.... 心情好多了,現在欠缺的就是錢了

app bundle and bundletool. 關於aab安裝問題

google 有說明年開始強制使用app bundle. 不然不准更新app. 但是產出的apk不再是apk了,而是aab. C:\release>adb install 6.aab Performing Streamed Install adb.exe: filename doesn't end .apk or .apex: 6.aab   不能透過adb install.... so, google 發表一個新tool: 去download bundletool...因為是java跨平台都可執行. https://github.com/google/bundletool/releases   You can extract the apks files from the aab file using the bundletool command. https://developer.android.com/studio/command-line/bundletool To generate an APK set for all device configurations (signed with a debug key) you can use:  bundletool build-apks --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks To deploy your app from an APK set, use the install-apks  bundletool install-apks --apks=/MyApp/my_app.apks test:   C:\release>java -jar bundletool.jar build-apks --bundle=6.aab --output=out_6.apks INFO: The APKs will be signed with the debug keystore found at 'C:\Users\mark\.android\debug.keystore'.   還是失敗,還要指定key才可以...  For Release apk command, example 1: bundle

ios app 上架時app icon要注意事項

按照apple ios app icon標準(App Icon Attributes): All app icons should adhere to the following specifications. 所有app icon須符合下列: -Format: PNG  , 一定要png...但全彩png size很大 .. -Color: 注意24bit不要有透明色在上面. -Layers: Flattened with no transparency. 絕不可以有alpha透明色. -Shape Square with no rounded corners 不可以有圓角,之後apple會統一用圓角特效上去. -Resolution: -iPhone X, iPhone 8 Plus, iPhone 7 Plus, and iPhone 6s Plus @3x -All other high-resolution iOS devices @2x ps: 建議不要使用 PDF 檔案.. pdf內是一個向量圖,本來是用來減少png的size太大問題. 但對於較複雜的圖像而言 PNG 的表現實際上是優於 PDF 的. iOS系統會自動把 30x30 的 PDF 圖檔做成 @2x 60x60 的 PNG 圖檔. 很複雜的官方說明: Image Size (px) File Name Used For App Store 512x512 iTunesArtwork App list in iTunes Do not include 1024x1024 iTunesArtwork@2x App list in iTunes on devices with retina display Do not include 120x120 (最重要!) Icon-60@2x.png Home screen on iPhone/iPod Touch with retina displ

SMR疊瓦式hdd致命缺陷被解決????!!!

新聞來源: https://tech.sina.cn/2019-12-25/detail-iihnzahi9980174.d.html 現在90%所有的硬碟 … 除了SSD 之外都是採用PMR 技術,但為容量增長而發展的SMR( 疊瓦式磁紀錄)會比較便宜不要踩地雷 。 PMR、SMR 硬碟分別是什麼? PMR (perpendicular magnetic recording,垂直磁性記錄). 寫入磁頭會比讀取磁頭來得大,因此硬碟供應商若要增加磁錄密度,就會儘可能讓寫入磁頭的尺寸縮小至物理極限為止。 SMR (shingled magnetic recording,疊瓦式磁性記錄). SMR 採用的技術是讓資料循序寫入,如其名稱所示,磁軌會如瓦片般堆疊在另一磁軌的部分面積上,藉此達到增加磁錄密度的目的。在此情況下,讀取磁頭仍可從磁軌上未被覆蓋的部分來讀取資料。   玩家對SMRHDD避之唯恐不及,因為這種HDD性能、可靠性都有問題,但它能提升HDD存儲密度大約1/4 PMR 與 SMR 的差異 當 SMR 硬碟上循序寫入新資料時,這些如瓦片般堆疊的磁軌仍可正常讀取, 並不影響讀取效能。 不過,一旦已寫入的資料要修改或覆寫時,寫入磁頭並不會直接在既有的磁軌上進行磁錄,以避免毀損相鄰的磁軌。 編輯後的資料會先在磁碟上的空白處寫入,原先舊資料的磁軌會暫時維持不動。 等到硬碟閒置時才會進行重新整理的機制,將原先磁軌上的舊資料自動清除,並重新成為可用空間以供新資料寫入。 就前述的重新整理機制而言, SMR 硬碟的閒置時間就顯得相當重要。如果 SMR 硬碟長時間進行密集的覆寫任務,則會沒有足夠的閒置時間來重新整理磁軌,暫時不動的既有資料磁軌數量會越來越多。接著導致 SMR 硬碟必須一邊寫入新資料,一邊重新整理舊磁軌,進而對讀寫效能造成某種程度的影響。 WD他們開發了名為Zonefs的文件系統,有望解決SMR HDD寫入數據時的弊端,同時也適用於SSD。 WD近年來一直在研究分區存儲(Zoned Storage),它將 HDD的LBA空間分成多個區塊,只能從每個區塊的開頭順序寫入數據,而且數據不能任意覆蓋。這種數據存儲技術可以改變SMR、SSD HDD存儲、寫入數據的方式,不會再像現在這樣有很多隨機

更改google drive預設存放目錄位置Change Google Drive Default Folder Location in Windows

Google drive預設存放位置是放在C:\Users\username\Google 雲端硬碟.有些人c槽是ssd,空間有限.如果一不小心,像google drive空間有1TB的人. SSD就被塞爆...需要改放在其他磁碟機..(例如c是ssd, D是一般硬碟..可能有幾TB) 1.如果之前已經安裝的人,首先先解除帳戶連結.解除後再刪除掉目前的舊的Google Drive 目錄.釋放已占空間.(不用擔心,因為已經備份到雲端,待會會自動再下載回來.) 2.再次登入帳戶,在最後一頁時.不要那麼快按確認,這裡有個"進階設定". 3.這邊可更改預設資料夾...我們把他改到D槽...或其他槽. 建一個新目錄,取個好記的名字,例如"[GoogleDrive]",加上特殊字元"[" "]"可讓資料夾排在最前面,將來比較好找.更改好之後,再選擇這新資料夾.   PS: 也建議大家不要把Google drive預設資料夾放在C:\Users\username\Google 雲端硬碟. 一則不方便找.二則重灌電腦時,會忘記這邊有資料,整理起來很麻煩.三是C通常是SSD,容量小,設在D槽(如果是HDD的話),可避免塞爆SSD.