Flutter開發遇到的一些常見的問題(持續更新)

  1. 當你遇到界面上鍵盤彈起時卻遮蓋佈局,或者彈起時佈局發生變化。

在這裏插入圖片描述加上該屬性 resizeToAvoidBottomPadding: false

  1. dart中用來計算 例如10的-6次方該怎麼寫
    首先引入 import ‘dart:math’;
    pow(10, -6) 注意返回的是一個num,需要toDouble();

  2. 做Android的同學都知道,當你用完一個controller,要記得註銷掉
    @override
    void dispose() {
    _textEditingController.dispose();
    super.dispose();
    }

  3. 界面延遲加載可以用FutureBuilder

  4. dart中list也可以進行排序
    list.sort((a,b) => a.sBaseCode.compareTo(b.sBaseCode));
    排序完之後打亂 list.shuffle()

  5. widget之間傳值
    1可以用構造方法
    MarketList _marketList;
    SecondPageMyItem(this._marketList);
    2也可以用接口
    typedef OnChanged(double num);

  6. 監聽不同widget數據變化可以用 eventbus,是的dart支持!!!

  7. IndexedStack相當於Android的一個Fragment,缺點是會提前加載,必要的情況下可以用pageview代替

  8. physics: NeverScrollableScrollPhysics()禁止滑動

  9. Listview嵌套Listview時,裏面的Listview內容顯示不全
    加上shrinkWrap: true, //爲true可以解決子控件必須設置高度的問題

  10. toStringAsFixed(2),小數點後精確到2位

  11. 未完待續。。。


  1. 使用AppBar後如何去掉左邊的返回箭頭。左邊的圖標對應的是leading,源代碼如下(吐槽一下,CSDN暫不支持dart語言):

    Widget leading = widget.leading;
    if (leading == null && widget.automaticallyImplyLeading) {
    if (hasDrawer) {
    leading = IconButton(
    icon: const Icon(Icons.menu),
    onPressed: _handleDrawerButton,
    tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
    );
    } else {
    if (canPop)
    leading = useCloseButton ? const CloseButton() : const BackButton();
    }
    }
    if (leading != null) {
    leading = ConstrainedBox(
    constraints: const BoxConstraints.tightFor(width: _kLeadingWidth),
    child: leading,
    );
    }
    修改方式爲, leading爲null,automaticallyImplyLeading爲false:

appBar: AppBar(
leading: null,
automaticallyImplyLeading: false,)
2. 使用flutter的canvas做文字繪製的時候用到的api爲TextPainter

  1. 使用flutter繪製控件的時候想做到控件超出屏幕範圍後自動換行,那麼請參考Wrap,可以輕鬆實現如下的佈局:

  2. 要實現類似安卓原生ViewPager的UI,請使用PageView,注意定義自己的PageController,然後可以利用PageController的jumpToPage(int)實現自定義的Page頁的跳轉

  3. 要實現類似頂部和底部導航欄,請參考TabBar,適當的時候可以和AppBar結合使用

  4. flutter is a SingleTickerProviderStateMixin but multiple tickers were created. 報錯,原因是多個地方調用setState請求重繪,但是state使用的是SingleTickerProviderStateMixin ,將其改成TickerProviderStateMixin即可。

  5. 解決類衝突的問題,比如,我自定義一個Banner.dart類,這個類跟系統的Banner衝突,那麼我們可以這樣解決。

import ‘package:flutter/material.dart’;
import ‘package:myproject/Banner.dart’ as myproject;

//這樣使用我們自己的Banner
myproject.Banner _myBanner;
//系統的Banner
Banner _banner;
8. 解決Android手機佈局浸入到狀態欄的問題,用一個SafeArea進行包裝即可,如下:

SafeArea(top: true,
child: MaterialApp(
home: ,
),);
9. 在切換tabbar或者pageview的時候要保存上一個tab widget的狀態,參考AutomaticKeepAliveClientMixin既可,如下:

//假如PageView有四個子頁面

@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: pageController,
children: [
ArticlesPage(),
ProjectPage(),
NavigationPage(),
CollectionArticlesPage(),
],
onPageChanged: changePage,
),
bottomNavigationBar: Navigations(_page, changePage));
}

//然後在子Page的State分別實現with AutomaticKeepAliveClientMixin,wantkeepAlive返回true

class ArticlesPageState extends State with AutomaticKeepAliveClientMixin{
@override
bool get wantKeepAlive => true;
}

class ProjectPageState extends State with AutomaticKeepAliveClientMixin{
@override
bool get wantKeepAlive => true;
}

class NavigationPageState extends State with AutomaticKeepAliveClientMixin{
@override
bool get wantKeepAlive => true;
}

class CollectionArticlesPageState extends State with AutomaticKeepAliveClientMixin{
@override
bool get wantKeepAlive => true;
}
10. Android手機啓動時候白屏的問題解決,android/app/src/main/res/drawable/launch_background.xml中定義了自定義splash的方法:

<?xml version="1.0" encoding="utf-8"?>
<!-- You can insert your own image assets here -->
<!-- <item>
    <bitmap
        android:gravity="center"
        android:src="@mipmap/launch_image" />
</item> -->
將註釋去掉,替換爲自己的launcher_image即可 。
  1. 界面存在輸入框的時候,點擊後軟鍵盤將頁面頂起來導致頁面重繪的問題(Android fitsystem),可以通過將Scaffold的resizeToAvoidBottomPadding屬性設置爲false來關閉重繪,如下:

return Scaffold(
resizeToAvoidBottomPadding: false,
);
12. 修改TextFiled的邊界寬度,可以通過decoration的contentPadding屬性進行修改,如下:

return TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8),
),
);
13. 如果想實現一個佈局,在某些條件下顯示,可以採用Offstage佈局,動態控制其offstage屬性值即可

  1. 如果出現彈出輸入法的時候導致Overflow錯誤,可以將佈局鑲嵌到SingleChildScrollView中,比如:

return Scaffold(
body: SingleChildScrollView(
child: Container(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height,
maxWidth: MediaQuery.of(context).size.width,
),
),
),
);
15. GridView的item寬高默認是1:1,可以通過修改childAspectRatio的值來進行寬高的修改,該值代表寬:高

  1. flutter中繪製虛線,使用path_drawing

  2. flutter 中禁用GridView的滾動,可以使用physics屬性,取值爲NeverScrollableScrollPhysics(),如下:

GridView.count(
physics: NeverScrollableScrollPhysics(),
);
18. flutter隱藏狀態欄,使用:

SystemChrome.setEnabledSystemUIOverlays([]);
19. 監聽某個widget是否已經渲染完成,使用WidgetsBinding,方法是在initstate或者build中註冊回調,如下:

WidgetsBinding.instance.addPostFrameCallback((callback){
  print("complete");
});
  1. flutter設置屏幕支持的方向:

以下設置爲設置整個項目運行到時候只允許橫屏,如果需要其他方向,可以參考設置。

SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]).then((_){
runApp(MyApp());
});
對於IOS來說,可能我們設置只允許橫屏了,但是效果確依舊可以豎屏,記得修改xcode的General–Deployment Info–Device Orientation屬性,自己勾選對應的方向,如下。

設置屏幕顯示方向,由於flutter中有bug,在IOS端可能不生效,需要插件支持,見 https://github.com/jadennn/flutter_orientation

  1. flutter設置多語言支持的時候發現在IOS端只顯示英語的bug,是由於xcode中默認沒有添加中文(其他語言類似)的選擇,解決辦法,在Info–Locallzations中選擇需要的語言,如下:

  2. flutter中禁止控件複用,可以使用不同的key,比如說,如果我們有一個stateful的控件,在initstate中進行了一些值的初始計算,在頁面中需要展示多個這樣的控件,不想多個控件公用同一套參數(換句話說,initstate只會在第一次初始化的時候調用),那麼可以設置不同的key。

  3. 裁剪圖片的方法:

import ‘dart:ui’ as DartUi;

///根據src和dst裁剪圖片
static DartUi.Image getCroppedImage(DartUi.Image image, Rect src, Rect dst) {
var pictureRecorder = new DartUi.PictureRecorder();
Canvas canvas = new Canvas(pictureRecorder);
canvas.drawImageRect(image, src, dst, Paint());
return pictureRecorder
.endRecording()
.toImage(dst.width.floor(), dst.height.floor());
}
24. 在不使用BuildContext的情況下進行頁面跳轉:

a. 創建一個global的key

static GlobalKey gNavigatorKey = new GlobalKey();
b. 在MaterialApp初始化的時候使用

return MaterialApp(
navigatorKey: Global.gNavigatorKey,
routes: <String, WidgetBuilder> {
‘/login’: (BuildContext context) => new LoginPage(),
},
//…代碼省略
c. 需要的地方使用:

Global.gNavigatorKey.currentState.pushNamedAndRemoveUntil(’/login’,(_) => false);
注意的是這種方法代價比較大,除非特殊情況,否則不建議使用。使用的時候根據不同的場景調用不同的push方法

  1. IOS卡在閃屏頁的解決方案:

以上原文鏈接:https://blog.csdn.net/email_jade/article/details/85317859

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章