中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Flutter開發中的技巧有哪些

發布時間:2022-01-11 16:46:49 來源:億速云 閱讀:108 作者:iii 欄目:移動開發

本篇內容介紹了“Flutter開發中的技巧有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

1.部件溢出

異常大致如下:

A RenderFlex overflowed by 22 pixels on the bottom.

導致的原因就是在水平或者垂直方向上的內容超過了父部件的大小。一般來說我們的頁面不存在這樣的問題,因為根據頁面的設計,事先可以預料到是否超出。不過要注意到有輸入法彈出的頁面。比如我下面的這個例子:

Flutter開發中的技巧有哪些

Flutter開發中的技巧有哪些

可以看到底部溢出了22個像素,可能在18:9的手機以上不太會出現這種問題,因為屏幕的高度足夠。但是這種16:9的手機可能會暴露出來。解決的方法有兩種:

包一層SingleChildScrollView,讓你的頁面可以滑動起來。

在Scaffold中設置resizeToAvoidBottomInset為false。默認為ture,防止部件被遮擋。如果使用了這個方法,如果底部有輸入框,則會造成遮擋。

大家可以根據實際需求選擇。

2.輸入框的遮擋

頁面如下:

Flutter開發中的技巧有哪些

底部有輸入框,同時“提交”的按鈕固定在底部。一開始覺得既然固定在底部,那就使用Stack配合Positioned來實現,然而就導致輸入法彈出時,發生遮擋。

Flutter開發中的技巧有哪些

上圖中,我選中了***一個輸入框,但因為輸入法默認都是在輸入框的下方彈出,然而上面蓋著這個“提交”按鈕,發生了遮擋。

最終我的解決方法就是使用Column配合Expanded來實現。修復后如下:

Flutter開發中的技巧有哪些

3.SafeArea

一旦有部件固定在頂部或者底部(嚴謹點的話可以說是在屏幕的四邊)。那我我們***使用SafeArea來包一下。因為Android 和  IOS都有狀態欄,甚至IOS還有叫做“HomeIndicator”的橫條。所以一不留神就會出現適配問題。

我們在Flutter中常使用的BottomNavigationBar 和 AppBar 其實就在內部處理了此類問題。以 AppBar源碼為例:

class _AppBarState extends State {    @override   Widget build(BuildContext context) {          if (widget.primary) {       appBar = SafeArea(  // <--- 1         top: true,         child: appBar,       );     }          return Semantics(       container: true,       child: AnnotatedRegion(         value: overlayStyle,         child: Material( // <--- 2           color: widget.backgroundColor             ?? appBarTheme.color             ?? themeData.primaryColor,           child: Semantics(             explicitChildNodes: true,             child: appBar,           ),         ),       ),     );   } }

所以使用方法為:

Material( // 需要顏色填充到邊界區域可以使用

Material( // 需要顏色填充到邊界區域可以使用   color: Colors.white,   child: SafeArea(     child: Container(),   ), )

還是上面的頁面,我們對比一下處理前后的效果:

Flutter開發中的技巧有哪些

Flutter開發中的技巧有哪些

4.善用Theme

Flutter  在開發中,讓人詬病的就是大量的嵌套,而我們只能盡量避免。比如將一些部件、屬性進行封裝,避免重復的書寫。不過封裝也講究使用場景。如果這種樣式的部件僅僅只是某一兩處使用,封裝顯得有點小題大做。并且封裝的大而全也會增加使用的復雜度。那么這時就可以使用Theme這種辦法。

舉一個例子,在下圖中圈起來的部分有三個按鈕,它們的高度相同,文字、圓角大小也相同。如果每一個都去設定這些屬性,未免太過麻煩。

Flutter開發中的技巧有哪些

這時我們使用Theme去統一修改它們的樣式,就會很方便了。

Theme(                data: Theme.of(context).copyWith(                 buttonTheme: ButtonThemeData(                   padding: const EdgeInsets.symmetric(horizontal: 16.0),                   minWidth: 64.0,                   height: 30.0,                   materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,                   shape:RoundedRectangleBorder(                     borderRadius: BorderRadius.circular(4.0),                   )                 ),                 textTheme: TextTheme(                   button: TextStyle(                     fontSize: 14.0,                   )                 )               ),               child: Row(                 children: [                   FlatButton(                     color: Color(0xFFF6F6F6),                     onPressed: (){},                     child: Text("聯系客戶"),                   ),                   ......                   FlatButton(                     color: Color(0xFFF6F6F6),                     onPressed: (){},                     child: Text("拒單"),                   )                 ],               ),             )

同時使用Theme還可以修改許多默認的設置,比如FlatButton的默認寬度為88,高度為36,但是FlatButton中沒有直接修改的屬性,網上好多的方法都是通過包一層Container去修改,不僅增加的嵌套,有些需求還不能達到。所以善用Theme可以讓你省時省力,不過缺點就是你需要去翻翻源碼,尋找使用這些Theme的地方。

5.注意平臺差異

注意部分組件在Android與IOS平臺之間的差異。

(1)Scaffold的  AppBar,AppBar中默認的title在Android中靠左顯示,IOS中居中顯示。如果需要兩個平臺效果統一,需要設置在AppBar中主動設置centerTitle屬性。同時AppBar的返回箭頭圖標也不相同,統一的話需要自定義leading。

Flutter開發中的技巧有哪些

(2)頁面跳轉如果使用MaterialPageRoute來做過渡效果,注意Android中新的頁面會從屏幕底部滑動到屏幕頂部,IOS中新的頁面會從屏幕右側滑動到屏幕左側。

如果需要兩個平臺效果統一,我們不使用自帶效果,可以自定義一個。

Navigator.push(context, PageRouteBuilder(transitionDuration: Duration(milliseconds: 300),   pageBuilder: (context, animation, secondaryAnimation){     return new FadeTransition( //使用漸隱漸入過渡,       opacity: animation,       child: TestPage(),     );   }) );

要么修改Theme,統一兩平臺的實現。:

class MyApp extends StatelessWidget {    static const Map _defaultBuilders = {     TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(),     TargetPlatform.iOS: FadeUpwardsPageTransitionsBuilder(),   };      @override   Widget build(BuildContext context) {          return MaterialApp(       theme: ThemeData(         pageTransitionsTheme: PageTransitionsTheme(           builders: _defaultBuilders         )       ),       ...     );   } }

(3)ScrollPhysics效果,可以滑動的部件都有一個physics屬性。滑動到邊界時,Android平臺為邊緣陰影的效果ClampingScrollPhysics,IOS為回彈效果BouncingScrollPhysics。如果需要統一,可以指定physics屬性。

(4)狀態欄方面,Android平臺默認是半透明的效果,IOS則是透明效果。比如Android要實現IOS的效果,可以設置狀態欄為透明。不過IOS要實現Android的效果則不行。。。,難道只能自定義?有知道方法的可以分享一下。

void main(){   runApp(MyApp());   // 透明狀態欄   if (Platform.isAndroid) {     SystemUiOverlayStyle systemUiOverlayStyle =      SystemUiOverlayStyle(statusBarColor: Colors.transparent);     SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);   } }

5.輸入鍵盤

當TextField的keyboardType屬性設置為TextInputType.phone  或TextInputType.number時,IOS系統彈出的數字輸入鍵盤沒有"完成"按鈕,導致輸入法無法關閉。當然了Android不存在這個問題。

比較成熟有效的方案是在鍵盤彈出的上方懸浮一個按鈕,點擊可以關閉鍵盤。當然了,這種問題也有對應的庫可以解決,我使用的是flutter_keyboard_actions來解決了這個問題。因為在Android端我發現了部分輸入法的兼容問題,所以只針對IOS做了處理。大家可以看一下前后對比圖,具體實現代碼可以參考flutter_keyboard_actions的文檔和我的項目代碼:

Flutter開發中的技巧有哪些

Flutter開發中的技巧有哪些

當然平臺差異不僅僅是這么多,比如IOS自帶側滑返回等。具體我們可以去查看調用TargetPlatform枚舉類的代碼。

如果你覺得這樣真麻煩,我給你支個大招,修改ThemeData的platform,指定一個平臺。

class MyApp extends StatelessWidget {      @override   Widget build(BuildContext context) {          return MaterialApp(       theme: ThemeData(         platform: TargetPlatform.android       ),       ...     );   } }

其次就是使用TextInputType.number在IOS中彈起的鍵盤沒有小數點符號。在輸入金額類型數據時,需要將keyboardType屬性設置為TextInputType.numberWithOptions(decimal:  true)。

6.keyboardType

keyboardType屬性主要含義為彈起的鍵盤類型,并不代表輸入數據的類型。

而在Android開發中,在EditText中設置android:inputType不僅可以指定彈起的鍵盤類型,同時也確定了輸入數據的類型,也就是內置了數據的格式校驗。Flutter中并沒有后者,所以可能一開始你是TextInputType.number,但是在輸入法中切換成中文鍵盤,一樣可以輸入中文字符。所以數據的校驗需要我們使用inputFormatters自己處理。

比如TextInputType.phone時可以使用WhitelistingTextInputFormatter 白名單校驗,只允許輸入0~9:

TextField(       keyboardType: TextInputType.phone,       inputFormatters: [WhitelistingTextInputFormatter(RegExp("[0-9]"))]     )

輸入密碼時可以使用BlacklistingTextInputFormatter 黑名單校驗,除去中文字符:

TextField(       keyboardType: TextInputType.text,       inputFormatters: [BlacklistingTextInputFormatter(RegExp("[\u4e00-\u9fa5]"))]     )

輸入小數時,可以自定義TextInputFormatter來限制輸入小數格式:

TextField(       keyboardType: TextInputType.numberWithOptions(decimal: true),       inputFormatters: [UsNumberTextInputFormatter()]     ) //來源:https://www.cnblogs.com/yangyxd/p/9639588.html class UsNumberTextInputFormatter extends TextInputFormatter {   static const defaultDouble = 0.001;   static double strToFloat(String str, [double defaultValue = defaultDouble]) {     try {       return double.parse(str);     } catch (e) {       return defaultValue;     }   }   @override   TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {     String value = newValue.text;     int selectionIndex = newValue.selection.end;     if (value == ".") {       value = "0.";       selectionIndex++;     } else if (value != "" && value != defaultDouble.toString() && strToFloat(value, defaultDouble) == defaultDouble) {       value = oldValue.text;       selectionIndex = oldValue.selection.end;     }     return new TextEditingValue(       text: value,       selection: new TextSelection.collapsed(offset: selectionIndex),     );   } }

7.InkWell

InkWell有的叫濺墨效果,有的叫水波紋效果。使用場景是給一些無點擊事件的部件添加點擊事件時使用(也支持長按、雙擊等事件),同時你也可以去修改它的顏色和形狀。

InkWell(   borderRadius: BorderRadius.circular(8.0), // 圓角   splashColor: Colors.transparent, // 濺墨色(波紋色)   highlightColor: Colors.transparent, // 點擊時的背景色(高亮色)   onTap: () {},// 點擊事件   child: Container(), );

不過有時你會發現并不是包一層InkWell就一定會有濺墨效果。主要原因是濺墨效果是在一個背景效果,并不是覆蓋的前景效果。所以InkWell中的child一旦有設置背景圖或背景色,那么就會遮住這個濺墨效果。如果你需要這個濺墨效果,有兩種方式實現。

(1)包一層 Material,將背景色設置在 Material中的color里。

Material(   color: Colors.white,   child: InkWell(), )

(2)使用Stack布局,將InkWell放置在上層。這種適用于給圖片添加點擊效果,比如Banner圖的點擊。

Stack(             children: [               Positioned.fill(                 child: Image(),               ),               Positioned.fill(                 child: Material(                   color: Colors.transparent,                   child: InkWell(                     splashColor: Color(0X40FFFFFF),                     highlightColor: Colors.transparent,                     onTap: () {},                   ),                 ),               )             ],           )

8.保持頁面狀態

比如點擊導航欄來回切換頁面,默認情況下會丟失原頁面狀態,也就是每次切換都會重新初始化頁面。這種情況解決方法就是PageView與BottomNavigationBar結合使用,同時子頁面State中繼承AutomaticKeepAliveClientMixin并重寫wantKeepAlive為true。代碼大致如下:

class _TestState extends State with AutomaticKeepAliveClientMixin{    @override   Widget build(BuildContext context) {     super.build(context);     return Container();   }      @override   bool get wantKeepAlive => true; }

9.依賴版本問題

首先這里建議凡是Flutter的插件在填寫版本號時不要使用^符號。

Flutter開發中的技巧有哪些

^符號意味著你可以使用此插件的***版本(大于等于當前版本)。這會導致什么問題呢?可能你前一天代碼還能跑起來,今天就編譯出錯了。因為這些插件中包括Android、IOS的所用依賴環境配置,常見的就是新版本使用了AndroidX的依賴,但是還有些插件并沒有使用AndroidX,導致了兩者的沖突。

我之前在看flutter-go的代碼時,就是因為webview的插件突然升級了,導致了安裝失敗。具體問題可以看這里。所以在代碼穩定的情況下不建議使用^符號。

發生了這種問題,有以下幾個解決方法:

  • 使用非AndroidX的版本插件。(優點就是見效快。缺點就是此插件后續的更新無法使用)

  • 手動修改插件的沖突,因為Flutter插件的代碼是可以直接修改的,所以你可以手動修改掉這些沖突,統一插件的版本(優點就是可以使用***的版本。缺點就是這種方法首先麻煩,其次不利于團隊開發使用)

我偏好使用第二種,只要做好修改的相關記錄就行,算是一勞永逸。

10.Flutter Android 打包

打包本身流程沒有問題,配置好簽名文件,執行flutter build  apk命令。但是發現打包后沒有將插件中的AndroidManifest.xml文件合并。比如我有使用image_picker插件,它的AndroidManifest.xml文件如下:

Flutter開發中的技巧有哪些

可以看到有權限的及Android  7.0FileProvider的聲明。諸如此類的信息沒有打包進去(但是引用xml中的flutter_image_picker_file_paths文件卻在),導致我實際使用這些功能時沒有反應,但是在平時的調試過程中卻是好的。

中間我發現打包后的App名稱也是之前的,懷疑是緩存問題,所以我手動刪除了項目根目錄的build與.gradle文件夾,重新打包就好了。所以打包后***檢查一下AndroidManifest.xml文件,避免此類緩存造成的問題。

11.其他

  1. Container 功能強大,設置寬高、padding、margin、背景色、背景圖、圓角、陰影等都可以使用它。

  2. 有些widget 自帶padding  屬性,所以不必多套一層Padding部件。(比如ListView、GridView、Container、ScrollView、Button )

  3. 盡量使用const來定義常量。比如padding、color、style 這些地方:

class Colours {   static const Color text_dark = Color(0xFF333333); }  Padding(   padding: const EdgeInsets.all(8.0),   child: Text(   "Test",   style: TextStyle(       fontSize: 26.0,       color: Colours.text_dark     )   ) )

4.Dart2中的new 關鍵字可選,所以就不要選了,哈哈!!

“Flutter開發中的技巧有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南华县| 微博| 扬州市| 蒙自县| 贞丰县| 韩城市| 福鼎市| 澜沧| 威远县| 乡宁县| 仁寿县| 霍林郭勒市| 裕民县| 麻城市| 南投市| 汪清县| 沂源县| 边坝县| 西和县| 衡水市| 招远市| 南城县| 建德市| 孙吴县| 东辽县| 大安市| 太康县| 遂川县| 龙江县| 岗巴县| 五大连池市| 稷山县| 徐闻县| 泗水县| 英吉沙县| 方城县| 南京市| 都江堰市| 金山区| 岚皋县| 和平区|