细节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),), //字体颜色和大小
),
],
),
);
}
}
//在别的页面
TranTitle('title'),
渐变背景色圆角按钮:
new Container(padding: EdgeInsets.only(top: 2),
margin: EdgeInsets.only(left: 20,right: 20), //按钮的左右margin(按钮太宽可以调整)
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(按钮太偏可以调整)
alignment: Alignment.center,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)), //圆角大小,与BoxDecoration保持一致,更美观
onPressed: () {//单击事件
Navigator.push(context, MaterialPageRoute(builder: context) => TaskDetailPage()); //跳转页面
},
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.
在报 空值错误 的时候,不一定是你加的值是空的 有可能是你使用的对象没有声明
跳转页面顺便关掉当前页面
Navigator.pushReplacement( context, MaterialPageRoute(builder: (BuildContext context) => MainPage()));
double保留后2位小数
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函数添加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…
androidstudio 界面创建卡死(使用命令创建)
flutter create -i objc -a java test1234
flutter create -i 语言 -a 语言 项目名
4、适用于Android和ios的base自适应顶部和底部状态的控件
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:math' as math;
import 'dart:io';
///base布局
class BaseLayout extends StatelessWidget {
///状态栏字体主题 FontStyle
final FontStyle stateFontStyle;
/// 是否显示状态栏
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); //计算状态栏的高度
double bottomPadding = MediaQuery.of(context).padding.bottom;
if (!isStateBar){
top = 0;
}
SystemUiOverlayStyle style = SystemUiOverlayStyle(
systemNavigationBarColor: Colors.white,// 底部状态栏背景颜色
systemNavigationBarDividerColor: null,
systemNavigationBarIconBrightness: Brightness.light, //dart 灰色 light 白色
statusBarColor: Colors.transparent, //状态栏背景
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;
}
}
}
/// 状态栏字体颜色
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函数内使用
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、搜索栏下面常用的搜索热词的流式布局
新建一个类
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类型没有小数点
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('参数名', mFile));
var response =
await Dio().post("http://jd.itying.com/imgupload", data: formData);
var data = response.data;
}
15、修改库源码的每次修改后想要生效都要先结束调试后在执行调试才会生效
16、双击退出
return WillPopScope(
onWillPop: () async {
if (_lastPressedAt == null ||
DateTime.now().difference(_lastPressedAt) > Duration(seconds: 2)) {
_lastPressedAt = DateTime.now();
CommUtil.toast('连续按两次返回键返回桌面');
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);
});