Flutter學習筆記-持續(xù)更新-歡迎提問題,交聊

細節(jié)1:Colum如何嵌套listview(可以滑動的)

Column(
...
  children: <Widget>[
    Expanded(
              child: Container(
                  ...
                child:  ListView(
                  padding: EdgeInsets.all(0), //這個是為去掉和頂部默認的高度
                  shrinkWrap: true, //主要是這個屬性
                  children: <Widget>[
                    buildListItem(context,2, '', '', '', '', ''),
                  ],
                ),
              ),
            )
  ]
)

單擊事件:GestureDetector和Listener

  Listener(
     onPointerUp: (e){
        //點擊動作
         print('測試');
     },
    child:  buildItem(1,'測試',2),
  ),         
GestureDetector(
 onTap: (){
     print('測試測試');
 },
 child: buildItem1('測試'),
),

常量類編寫:

class TestColor{
  static const shen = Color.fromARGB(255, 238, 133, 51);
  static const qian = Color.fromARGB(255, 236, 181, 65);
  static const gray = Color(0xFFEEEEEE);
}

自定義標題類的封裝

//透明的titlebar
class TranTitle extends StatefulWidget{
  String title = "";
  TranTitle(this.title);
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return TranTitleState(title);
  }
}
class TranTitleState extends State<TranTitle>{
  String title = "";
  TranTitleState(this.title);
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      height: 50,
      color: Colors.transparent,   // 背景顏色
//      decoration: BoxDecoration(   //背景漸變色
//          gradient: LinearGradient(colors: <Color>[
//            Color.fromARGB(255, 138, 133, 81),
//            Color.fromARGB(255, 136, 141, 65),
//          ])
//      ),
      child: Stack(
        children: <Widget>[
          Container(
            padding: EdgeInsets.only(left: 10),
            alignment: Alignment.centerLeft,
            child: GestureDetector(
              onTap: (){
                print('返回上一頁');
                Navigator.pop(context);  //返回
              },
              child: Image.asset('art/titlebar_back_white.png',height: 18,width: 18,),  
            ),
          ),
          Center(
            child: Text(title,style: TextStyle(fontSize: 16,color: Colors.white),), //字體顏色和大小
          ),
        ],
      ),
    );
  }
}
titlebar_back_white.png
//在別的頁面
TranTitle('title'),

漸變背景色圓角按鈕:

new Container(padding: EdgeInsets.only(top: 2),
                        margin: EdgeInsets.only(left: 20,right: 20), //按鈕的左右margin(按鈕太寬可以調(diào)整)
                        child:  new FlatButton(
                          child: new Container(
                            decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(20), //圓角大小,與BoxDecoration保持一致,更美觀
                              gradient: LinearGradient(colors: <Color>[
                                Color.fromARGB(255, 38, 13, 51),
                                Color.fromARGB(255, 26, 11, 65),
                              ]),
                            ),
                            child: new Text("測試",style: new TextStyle(fontSize: 14,fontWeight: FontWeight.w300),),
                            padding: EdgeInsets.fromLTRB(10, 3, 10, 3), //按鈕的上下padding(按鈕太偏可以調(diào)整)
                            alignment: Alignment.center,
                          ),
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(20)), //圓角大小,與BoxDecoration保持一致,更美觀
                          onPressed: () {//單擊事件
                         Navigator.push(context, MaterialPageRoute(builder: context) => TaskDetailPage()); //跳轉(zhuǎn)頁面
                          },
                          textColor: Colors.white,
                        ),
                      ),

帶邊框和背景顏色按鈕:

FlatButton(
          textColor: Colors.white,  //背景顏色
          onPressed: (){ //點擊事件
            print('點擊事件');
          },
          child: Center(
            child: Container(
              width: 80, //按鈕的寬
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(20),  //圓角
                border: Border.all(color: Colors.amber, width: 1), //邊框顏色
              ),
              alignment: Alignment.center,
              padding: EdgeInsets.only(top: 2,bottom: 2),
              child: Text('測試',style: TextStyle(color: Colors.amber),), //字體顏色
            ), 
          ),
        ),

橫向ListView

scrollDirection: Axis.horizontal, //ListView設置

錯誤1:
[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: 'package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 110 pos 12: '_positions.isNotEmpty': ScrollController not attached to any scroll views.
在報 空值錯誤 的時候,不一定是你加的值是空的 有可能是你使用的對象沒有聲明

跳轉(zhuǎn)頁面順便關掉當前頁面

Navigator.pushReplacement( context, MaterialPageRoute(builder: (BuildContext context) => MainPage()));

double保留后2位小數(shù)

double vv = 12.3333333;
vv.toStringAsFixed(2);

Flutter打包IPA報錯Could not find an option named "track-widget-creation".

1、進入項目目錄
2、flutter build ios --release

軟鍵盤頂起布局

Scaffold(
  resizeToAvoidBottomPadding: false,
)

點擊空白處關閉軟鍵盤

GestureDetector(
    behavior: HitTestBehavior.translucent,
    onTap: () {
        // 觸摸收起鍵盤
        FocusScope.of(context).requestFocus(FocusNode());
    },
    child: 布局
}

ios報錯:ld: framework not found Pods_Runner

1.項目藍色圖標->Targets->General->Linked Frameworks and Libraries
2.刪除 Pods_Alamofire___.framework

flutter打包IOS應用前命令
xcode報錯
1、Could not find an option named "track-widget-creation".
2、flutter -h....什么的忘記了
flutter build ios --release

Android Studio
? Flutter plugin not installed; this adds Flutter specific functionality.
? Dart plugin not installed; this adds Dart specific functionality.
? Android Studio not found at /path/to/android/studio/Contents

flutter config --android-studio-dir=""
flutter config --android-sdk=""

打包提示(ios打包出來的閃退,android正常)
Warning: Podfile is out of date
This can cause a mismatched version of Flutter to be embedded in your app,
which may result in App Store submission rejection or crashes.
If you have local Podfile edits you would like to keep, see
https://github.com/flutter/flutter/issues/24641 for instructions.
To regenerate the Podfile, run:
rm ios/Podfile

1 刪除項目的Podfile和Podfile.lock
2 flutter build ios --release

Unhandled Exception: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized.
If you're running an application and need to access the binary messenger before runApp() has been called (for example, during plugin initialization), then you need to explicitly call the WidgetsFlutterBinding.ensureInitialized() first.

在lib的main.dart的main函數(shù)添加WidgetsFlutterBinding.ensureInitialized();

void main() {
  //初始化-(不初始化白屏,初始化真機閃退)
  WidgetsFlutterBinding.ensureInitialized();
  ......
}

添加高斯模糊層

import 'dart:ui';

buildss(){
    return Stack(
      children: <Widget>[
        Container(
          height: CommUtil.height(800),
          child: Image.network('圖片的地址',fit: BoxFit.fitHeight,),
        ),
        Container(
          width: CommUtil.width(1080),
          height: CommUtil.height(800),
          child:  ClipRRect(
            child: BackdropFilter(
              filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
              child: Container(
                color: Colors.white.withOpacity(0.2),
              ),
            ),
          ),
        ),
      ],
    );
  }

flutter命令
Waiting for another flutter command to release the startup lock…


image.png

androidstudio 界面創(chuàng)建卡死(使用命令創(chuàng)建)
flutter create -i objc -a java test1234
flutter create -i 語言 -a 語言 項目名

4、適用于Android和ios的base自適應頂部和底部狀態(tài)的控件

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:math' as math;
import 'dart:io';
///base布局
class BaseLayout extends StatelessWidget {
  ///狀態(tài)欄字體主題  FontStyle
  final FontStyle stateFontStyle;
  /// 是否顯示狀態(tài)欄
  final bool isStateBar;
  Color background;
  BoxDecoration topColor;
  Widget child;


  BaseLayout({@required this.stateFontStyle,@required this.isStateBar,@required this.child,this.background = Colors.white,this.topColor});



  @override
  Widget build(BuildContext context) {
    EdgeInsets padding = MediaQuery.of(context).padding;
    double top = math.max(padding.top , EdgeInsets.zero.top); //計算狀態(tài)欄的高度
    double bottomPadding = MediaQuery.of(context).padding.bottom;
    if (!isStateBar){
      top = 0;
    }

    SystemUiOverlayStyle style = SystemUiOverlayStyle(
      systemNavigationBarColor: Colors.white,// 底部狀態(tài)欄背景顏色
      systemNavigationBarDividerColor: null,
      systemNavigationBarIconBrightness: Brightness.light, //dart 灰色  light 白色
      statusBarColor: Colors.transparent, //狀態(tài)欄背景
      statusBarIconBrightness: isLight(stateFontStyle),
      statusBarBrightness: isLight(stateFontStyle),
    );

    return Scaffold(
      backgroundColor: background,
      body: AnnotatedRegion<SystemUiOverlayStyle>(
        value: style,
        child: Flex(
          direction: Axis.vertical,
          children: <Widget>[
            Container(
              width: double.infinity,
              height: top,
              decoration: topColor,
            ),
            Expanded(child: child),
            Container(
              width: double.infinity,
              color: Colors.white,
              height: bottomPadding,
            ),
          ],
        ),
      ),
    );
  }
  ///判斷是否是白色字體
  Brightness isLight(FontStyle style){
    if (style == FontStyle.dark){
      return Platform.isIOS ? Brightness.dark : Brightness.light;
    }else{
      return Platform.isIOS ? Brightness.light: Brightness.dark;
    }
  }

}
/// 狀態(tài)欄字體顏色
enum FontStyle{
    ///白色
   light,
    ///黑色
   dark,
}

5、shared_preferences 控件
導入包

shared_preferences: ^0.5.6

工具類

import 'package:shared_preferences/shared_preferences.dart';

class SpUtil {
  ///保存String類型的Key
  static Future putString(String key,String value) async{
    SharedPreferences preferences = await SharedPreferences.getInstance();
    preferences.setString(key, value);
  }
  ///獲取String類型的Key
  static Future<String> getString(String key) async{
    SharedPreferences preferences = await SharedPreferences.getInstance();
    return preferences.getString(key);
  }

  ///保存Bool類型的Key
  static Future putBoolean(String key,bool value) async{
    SharedPreferences preferences = await SharedPreferences.getInstance();
    preferences.setBool(key, value);
  }
  ///獲取Bool類型的Key
  static Future<bool> getBoolean(String key) async{
    SharedPreferences preferences = await SharedPreferences.getInstance();
    return preferences.getBool(key);
  }


  ///保存int類型的Key
  static Future putInt(String key,int value) async{
    SharedPreferences preferences = await SharedPreferences.getInstance();
    preferences.setInt(key, value);
  }
  ///獲取int類型的Key
  static Future<int> getInt(String key) async{
    int vv = -1;
    try{
      SharedPreferences preferences = await SharedPreferences.getInstance();
      vv = preferences.getInt(key);
    }catch(e){
    }
    return vv;
  }
}

6、屏幕自適應的庫
導入包

  flutter_screenutil: ^0.7.0

使用

//初始化屏幕的尺寸,在第一個頁面的build函數(shù)內(nèi)使用
ScreenUtil.instance = ScreenUtil(width: 1080, height: 1920)
      ..init(context);
//用法,可以新建一個公共的工具類
//只使用width和fontSize方法就好,使用height的話,某些機型的寬高比更這個比例不一樣,會有一點小差別,導致顯示不全
 static double width(num num){
    return ScreenUtil.getInstance().setWidth(num);
  }

  static double height(num num){
    return ScreenUtil.getInstance().setHeight(num);
  }

  static double fontSize(num num){
    return ScreenUtil.getInstance().setSp(num);
  }

7、搜索欄下面常用的搜索熱詞的流式布局


WeChat819918f0c5e814d2fb475c242c3f16f6.png

新建一個類

import 'package:flutter/material.dart';


///流式布局
class MyFlowDelegate extends FlowDelegate {
  @override
  var _margin = EdgeInsets.zero;
  MyFlowDelegate(this._margin);
  void paintChildren(FlowPaintingContext context) {
    var offsetX = _margin.left;
    var offsetY = _margin.top;
    var winSizeWith = context.size.width;
    for(int i = 0; i < context.childCount; i++){
      var w = offsetX + context.getChildSize(i).width + _margin.right;
      if(w < winSizeWith){
        context.paintChild(i,transform: Matrix4.translationValues(offsetX,offsetY,0.0));
        offsetX = w + _margin.left;
      }else{
        offsetX = _margin.left;
        offsetY += context.getChildSize(i).height + _margin.bottom + _margin.top;
        context.paintChild(i,transform: Matrix4.translationValues(offsetX, offsetY, 0.0));
        offsetX += context.getChildSize(i).width + _margin.right;
      }
    }
  }

  @override
  bool shouldRepaint(FlowDelegate oldDelegate) {
    throw UnimplementedError();
  }
}

在頁面中使用

8 在使用dio請求中,如果有需要切換請求頭之類的,必須將對象設置為空,不然設置了請求頭也是沒用的

9、Text設置行高要設置Text里面的height屬性

10、修改軟鍵盤的主題色

  //dart 黑色  ligtht 白色
 TextField(
        keyboardAppearance:Brightness.light,
      ),

11、提示報錯 Incorrect use of ParentDataWidget.
Expanded 一定要在 Column 或 Row中使用,不如會提示這個錯誤,雖然不會運行不起來,但是在android一些手機上,可能會顯示不全

12、防止初始化沒完成爆紅,攔截掉

void showLoadDialog(String title,{bool mask = false}){
    ///例如顯示加載dialog
    Future.delayed(Duration.zero, () { ///防止初始化沒完成爆紅,攔截掉
      showDialog<Null>(
          context: context,
          barrierDismissible:mask,
          builder: (context){
            return CustomDialog(///一個透明的布局
              width: CommUtil.width(300),
              height: CommUtil.width(300),
              chlid: Container(
                alignment: Alignment.center,
                child:Column(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    CircularProgressIndicator(),
                    Text(title)
                  ],
                ),
              ),
            );
          }
      );
    });
  }

13、flutter控件TextField number類型沒有小數(shù)點
keyboardType: TextInputType.numberWithOptions(decimal: true),

14、dio 3.0.9 上傳文件

  void uploadFile(File file) async{
    FormData formData = FormData();
    MultipartFile mFile = await MultipartFile.fromFile(file.path);
    formData.files.add(MapEntry('參數(shù)名', mFile));
    var response =
        await Dio().post("http://jd.itying.com/imgupload", data: formData);
    var data = response.data;
    
  }

15、修改庫源碼的每次修改后想要生效都要先結(jié)束調(diào)試后在執(zhí)行調(diào)試才會生效

16、雙擊退出

    return WillPopScope(
      onWillPop: () async {
        if (_lastPressedAt == null ||
            DateTime.now().difference(_lastPressedAt) > Duration(seconds: 2)) {
          _lastPressedAt = DateTime.now();
          CommUtil.toast('連續(xù)按兩次返回鍵返回桌面');
          return false;
        } else {
          exit(0);
          _timer.cancel();
          return true;
        }
      },
      child: Scaffold(body: Text('控件'),),
    );

17、顯示16進制的字符串的顏色


import 'package:flutter/material.dart';

class HexColor extends Color {
  static int _getColorFromHex(String hexColor) {
    hexColor = hexColor.toUpperCase().replaceAll("#", "");
    hexColor = hexColor.replaceAll('0X', '');
    if (hexColor.length == 6) {
      hexColor = "FF" + hexColor;
    }
    return int.parse(hexColor, radix: 16);
  }

  HexColor(final String hexColor) : super(_getColorFromHex(hexColor));
}

18、在輸入框左邊添加圖標(有屬性)

 return TextField(
      decoration: InputDecoration(
          ///輸入框左邊的圖標
          prefixIcon:Icon(Icons.image)
      ),
    );

19、dart List排序

List ss = [
{
'createtime':111111,
},
{
'createtime':2222,
},
{
'createtime':33333,
},
];
 mList.sort((a,b){
              return a.createtime.compareTo(b.createtime);
            });
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容