Flutter開發問題合集

1.ListView和GridView嵌套滑動衝突問題

ListView(
          shrinkWrap: true,//增加
          children: <Widget>[
            new GridView.count(
            physics: new NeverScrollableScrollPhysics(),//增加
            shrinkWrap: true,//增加
            crossAxisCount: 3,
            children:<Widget>[]
          ],
        )

關鍵代碼:

GridView添加 physics: new NeverScrollableScrollPhysics() 和 shrinkWrap: true

2.Tab切換或滑動的狀態保存問題

如果是底部導航欄切換推薦使用IndexedStack組件,會自動保存狀態,也可按如下方案:
1.State組件實現AutomaticKeepAliveClientMixin
2.重寫wantKeepAlive爲true
實例:

class _TabViewWidgetState extends State<TabViewWidget> with AutomaticKeepAliveClientMixin{

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return SizeBox();
  }

  @override
  bool get wantKeepAlive => true;

3.庫名衝突

比如自定義繪製 ParagraphBuilderpushStyle方法,你會發現TextStyle導入的包始終是爆紅的,這是因爲庫名衝突了,解決方案:

import 'dart:ui' as other; //重點 命一個別名

class MyDraw extends CustomPainter{
  @override
  void paint(Canvas canvas, Size size) {
    final textStyle = other.TextStyle( //前面加一個別名就好了
       .........
    );
 
    final paragraphBuilder = ParagraphBuilder(paragraphStyle)
      ..pushStyle(textStyle)
    .....代碼省略
  }
}

需要注意的是別名最好不要和類名一樣,因爲如果需要調用靜態方法或者導入方法會報錯,造成別名和類名的衝突

4 jsonDecode解析出來的map是什麼類型?

打印一下就知道,結果是LinkedHashMap

5 Positioned 大小問題

Positioned需要定義3個方向的屬性纔會有寬高屬性,否則是無法確定寬高的,子組件也無寬高那麼就會報錯,示例如下:

Positioned(
  ....
top: 0,
 left: 0,
 right: 0,
)

6 TextField的一些問題解決方案

1.去掉底部文字計數器
在InputDecoration屬性裏設置counterText :' '
2.TextField無邊框文字居中問題

經過測試TextField設置了border: InputBorder.none無邊框後文字無法居中,設置了邊框後又可以。所以實現無邊框和文字居中的方案是添加一個透明邊框:

border: OutlineInputBorder(
                                        borderSide: BorderSide(
                                          color: Colors.transparent,
                                        ),
                                      ),
                                      enabledBorder: OutlineInputBorder(
                                        borderSide: BorderSide(
                                          color: Colors.transparent,
                                        ),
                                      ),
                                      disabledBorder: OutlineInputBorder(
                                        borderSide: BorderSide(
                                          color: Colors.transparent,
                                        ),
                                      ),
                                      focusedBorder: OutlineInputBorder(
                                        borderSide: BorderSide(
                                          color: Colors.transparent,
                                        ),
                                      )
2.TextField換行問題

有時候需要實現個備份填寫等長文本,需要限制字數和自動換行,可以這麼實現:

Container(
                alignment: Alignment.topLeft,
                decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(Radius.circular(8)),
                    color: editBackground),
                child: TextField(
                  keyboardType: TextInputType.multiline, //多文本
                  minLines: 1, 
                  maxLines: 20,  //一定要設置,不然不會換行,具體設置多大視需求而定
                  maxLength: 200, //設置了這個底部就會出現文字計數器
                  decoration: InputDecoration(
                      isDense: true,  //解決多行文本之間的間距
                      border: OutlineInputBorder(
                        borderSide: BorderSide(
                          color: Colors.transparent,
                        ),
                      ),
                      enabledBorder: OutlineInputBorder(
                        borderSide: BorderSide(
                          color: Colors.transparent,
                        ),
                      ),
                      disabledBorder: OutlineInputBorder(
                        borderSide: BorderSide(
                          color: Colors.transparent,
                        ),
                      ),
                      focusedBorder: OutlineInputBorder(
                        borderSide: BorderSide(
                          color: Colors.transparent,
                        ),
                      )),
                ),
              )

7. setStatue更新問題

1.setStatue出現不能更新的問題,需要着重檢查更新佈局的context, 父佈局一定是具有State狀態管理功能的組件,否則不能更新
2.彈窗dialog不能直接調用setStatue進行更新,因爲context是不一樣的,ui刷新並不能更新到彈窗,怎麼辦呢,可使用StatefulBuilder局部更新組件來進行更新. 簡單使用:

StatefulBuilder(
                      builder: (BuildContext context,
                          void Function(void Function()) _statue) {
                        return InkWell(
                          onTap: () => {
                          _statue(() {  //調用_statue來完成局部更新,調用後StatefulBuilder裏的組件會重新刷新一遍
                        mBean.oilTag = "$i$title";  
                         })
                          },
                          child: Container(
                            alignment: Alignment.centerRight,
                            child: Text(
                              isNotEmpty(mBean.oilTag) ? mBean.oilTag! : "請選擇",
                              style: TextStyle(
                                  color: isNotEmpty(mBean.oilTag)
                                      ? colorText
                                      : color999),
                            ),
                          ),
                        );
                      },
                    )

或者直接使用彈窗的context進行更新,示例如下:

(context as Element).markNeedsBuild(); //標記這個context下的組件需要更新

這樣彈窗會從上到下更新一遍ui
關於這一塊的詳細解釋,請參考這裏,篇幅有限,不詳細解析哈。

  1. ValueNotifier不更新
    檢查ValueNotifier裏的對象和新的更改的對象是否是同一個,例如集合,如果操作的是同一個集合,那麼是不會觸發更新的
  2. 簡單總結一下局部更新的一些組件:
  • StatefulBuilder: 該組件相當於是一個小型的StatefulWidget,暴露出一個方法用於局部更新
  • ValueListenableBuilder: 當監聽的數據有變化時更新,一般配合ValueNotifier使用
  • StreamBuilder: 流數據變化監聽,AsyncSnapshot會有多種狀態,使用connectionState可以獲取對應的狀態,適合網絡請求等耗時操作
  • FutureBuilder: Future方法監聽, 與StreamBuilder 差不多,但是傳入的是一個Future方法,需要注意當調用全局的setState會有重複刷新的問題,需要額外處理規避

8.流(Stream)的使用

分享一篇講解的分享好的文章
“四大天王”:StreamController,Sink,Stream,StreamSubscription 的詳細說明

9.集成地圖問題

集成地圖提示

java.lang.NoClassDefFoundError: Failed resolution of: Lcom/amap/api/maps/AMapOptions;

檢查一遍發現AMapOptions有這個類呀,怎麼會找不到,後面發現這個類和源碼裏導入的類包名不一樣,我使用的是2D地圖的類,而flutter裏的是使用的3D的,破案了,把安卓裏引入的地圖包從2d改成3d即可。

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