输入框(TextField
)去边框
TextField(
decoration: InputDecoration(
border: InputBorder.none
)
超出的文字显示省略号
Text(
item.title,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: ...
),
图片加占位符和圆角
Container(
padding: const EdgeInsets.all(20.0),
width: double.infinity,
height: 150,
child: ClipRRect(
borderRadius: BorderRadius.circular(6.0),
child: FadeInImage.assetNetwork(
placeholder: "images/default.jpg",
image: 'https://via.placeholder.com/650x200',
fit: BoxFit.cover,
),
),
)
设置Container
全屏宽度
Container(
width: MediaQuery.of(context).size.width,
)
设置部分圆角
borderRadius: const BorderRadius.only(topLeft: const Radius.circular(10.0), topRight: const Radius.circular(10.0))
点击空白区域收回软键盘
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
// 触摸收起键盘
FocusScope.of(context).requestFocus(FocusNode());
},
child: *******
}
禁止 ScrollView 滑动
physics: const NeverScrollableScrollPhysics()
showDialog() 或 showBottomSheet() 更改状态
因这两个方法是生成了新的路由了,因此没办法用当前页面的setState来做状态更新。
这里使用 StatefulBuilder 组件更新 dialog 内的状态
StatefulBuilder(
builder: (context, state) {
//当前使用新的方法 state 来更新状态
state((){});
});
路由重定向
Navigator.of(context).pushAndRemoveUntil(
new MaterialPageRoute(builder: (context) => new MyApp() ),
(route) => route == null
);
顶部固定剩余部分滑动
// 方式一
LayoutBuilder(
builder: (context, constrains) {
return Column(
children: <Widget>[
sizeBox(
height: 50,
child: ...
),
SizedBox(
height: constrains.maxHeight-50,
child: ...
)
]
)
}
);
// 方式二
SizeBox(
width: 375,
height: 800,
child: Column(
children: [
sizeBox(
height: 50,
child: ...
),
Expanded(
child: ...
)
]
)
)
在widget
列表中异步循环渲染组件
List renderData = [...];
Iterable<Widget> get widgetList sync* {
for (int i = 0; i < renderData.length; i++) {
yield Container(...);
}
}
// 在`widget`列表中使用(Row, Column, ListView...)
Row(
...
children: widgetList.toList()
)
设置为宽度为最大宽度
MediaQuery.of(context).size.width
设置渐变
BoxDecoration(
...
gradient: LinearGradient(
begin: Alignment(0, 0),
end: Alignment(1, 1),
colors: [Color(0xff1eccfe), Color(0xff0191fa)]
)
)
统一Android和IOS头部
Scaffold(
appBar: AppBar(
title: Text('标题', style: TextStyle(color: Color(0xff333333), fontSize: 22)),
leading: new IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.chevron_left, color: Color(0xff333333), size: 22),
),
elevation: 0,
),
body: ...
)
自定义tab
class Orders extends StatefulWidget {
final dynamic option;
Orders(this.option);
OrdersState createState () => OrdersState();
}
class OrdersState extends State<Orders> {
final List<Tab> myTabs = <Tab>[
new Tab(text: '全部'),
new Tab(text: '已完成'),
new Tab(text: '未完成'),
];
TabController _controller;
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: myTabs.length,
child: Scaffold(
appBar: AppBar(
title: Text('订单管理', style: TextStyle(color: kLingyiText500, fontSize: ScreenUtil.getInstance().setSp(32))),
leading: new IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.chevron_left, color: kLingyiText500, size: ScreenUtil.getInstance().setSize(42)),
),
bottom: TabBar(
tabs: myTabs,
controller: _controller,
indicatorColor: Colors.red,
indicatorSize: TabBarIndicatorSize.tab,
isScrollable: false,
labelColor: Colors.red,
unselectedLabelColor: Colors.black,
indicatorWeight: 5.0,
labelStyle: TextStyle(height: 1),
),
),
body:TabBarView(
children: myTabs.map((Tab tab) {
// var tabIndex = myTabs.indexOf(tab);
// return OrderBody(tabIndex);
...
}).toList(),
)
)
);
}
}
webView的使用
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class Webview extends StatelessWidget {
final dynamic option;
Webview(this.option);
@override
Widget build(BuildContext context) {
String url = option.query['url'];
String title = option.query['title'];
return Scaffold(
appBar: AppBar(
title: Text(title),
leading: new IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.chevron_left),
),
elevation: 0,
),
body: WebView(
initialUrl: url,
javascriptMode: JavascriptMode.unrestricted,
),
);
}
}