細(xì)節(jié)1:Colum如何嵌套listview(可以滑動(dòng)的)
Column(
...
children: <Widget>[
Expanded(
child: Container(
...
child: ListView(
padding: EdgeInsets.all(0), //這個(gè)是為去掉和頂部默認(rèn)的高度
shrinkWrap: true, //主要是這個(gè)屬性
children: <Widget>[
buildListItem(context,2, '', '', '', '', ''),
],
),
),
)
]
)
單擊事件:GestureDetector和Listener
Listener(
onPointerUp: (e){
//點(diǎn)擊動(dòng)作
print('測(cè)試');
},
child: buildItem(1,'測(cè)試',2),
),
GestureDetector(
onTap: (){
print('測(cè)試測(cè)試');
},
child: buildItem1('測(cè)試'),
),
常量類編寫:
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);
}
自定義標(biāo)題類的封裝
//透明的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),), //字體顏色和大小
),
],
),
);
}
}
//在別的頁面
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("測(cè)試",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: (){ //點(diǎn)擊事件
print('點(diǎn)擊事件');
},
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('測(cè)試',style: TextStyle(color: Colors.amber),), //字體顏色
),
),
),
橫向ListView
scrollDirection: Axis.horizontal, //ListView設(shè)置
錯(cuò)誤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.
在報(bào) 空值錯(cuò)誤 的時(shí)候,不一定是你加的值是空的 有可能是你使用的對(duì)象沒有聲明
跳轉(zhuǎn)頁面順便關(guān)掉當(dāng)前頁面
Navigator.pushReplacement( context, MaterialPageRoute(builder: (BuildContext context) => MainPage()));
double保留后2位小數(shù)
double vv = 12.3333333;
vv.toStringAsFixed(2);
Flutter打包IPA報(bào)錯(cuò)Could not find an option named "track-widget-creation".
1旧蛾、進(jìn)入項(xiàng)目目錄
2、flutter build ios --release
軟鍵盤頂起布局
Scaffold(
resizeToAvoidBottomPadding: false,
)
點(diǎn)擊空白處關(guān)閉軟鍵盤
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
// 觸摸收起鍵盤
FocusScope.of(context).requestFocus(FocusNode());
},
child: 布局
}
ios報(bào)錯(cuò):ld: framework not found Pods_Runner
1.項(xiàng)目藍(lán)色圖標(biāo)->Targets->General->Linked Frameworks and Libraries
2.刪除 Pods_Alamofire___.framework
flutter打包IOS應(yīng)用前命令
xcode報(bào)錯(cuò)
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 刪除項(xiàng)目的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() {
//初始化-(不初始化白屏剃毒,初始化真機(jī)閃退)
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…
androidstudio 界面創(chuàng)建卡死(使用命令創(chuàng)建)
flutter create -i objc -a java test1234
flutter create -i 語言 -a 語言 項(xiàng)目名
4病袄、適用于Android和ios的base自適應(yīng)頂部和底部狀態(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); //計(jì)算狀態(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 控件
導(dǎo)入包
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赘阀、屏幕自適應(yīng)的庫
導(dǎo)入包
flutter_screenutil: ^0.7.0
使用
//初始化屏幕的尺寸益缠,在第一個(gè)頁面的build函數(shù)內(nèi)使用
ScreenUtil.instance = ScreenUtil(width: 1080, height: 1920)
..init(context);
//用法,可以新建一個(gè)公共的工具類
//只使用width和fontSize方法就好基公,使用height的話幅慌,某些機(jī)型的寬高比更這個(gè)比例不一樣,會(huì)有一點(diǎn)小差別轰豆,導(dǎo)致顯示不全
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胰伍、搜索欄下面常用的搜索熱詞的流式布局
新建一個(gè)類
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請(qǐng)求中,如果有需要切換請(qǐng)求頭之類的酸休,必須將對(duì)象設(shè)置為空骂租,不然設(shè)置了請(qǐng)求頭也是沒用的
9、Text設(shè)置行高要設(shè)置Text里面的height屬性
10斑司、修改軟鍵盤的主題色
//dart 黑色 ligtht 白色
TextField(
keyboardAppearance:Brightness.light,
),
11菩咨、提示報(bào)錯(cuò) Incorrect use of ParentDataWidget.
Expanded 一定要在 Column 或 Row中使用,不如會(huì)提示這個(gè)錯(cuò)誤陡厘,雖然不會(huì)運(yùn)行不起來抽米,但是在android一些手機(jī)上,可能會(huì)顯示不全
12糙置、防止初始化沒完成爆紅云茸,攔截掉
void showLoadDialog(String title,{bool mask = false}){
///例如顯示加載dialog
Future.delayed(Duration.zero, () { ///防止初始化沒完成爆紅,攔截掉
showDialog<Null>(
context: context,
barrierDismissible:mask,
builder: (context){
return CustomDialog(///一個(gè)透明的布局
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ù)點(diǎn)
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)試才會(huì)生效
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進(jìn)制的字符串的顏色
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、在輸入框左邊添加圖標(biāo)(有屬性)
return TextField(
decoration: InputDecoration(
///輸入框左邊的圖標(biāo)
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);
});