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()方式.
所以我覺得換個領域,很多觀念都會有所不同.
留言
張貼留言