1.Container
1. Container设置圆角
Container(
width: widget.width,
height: widget.height,
decoration: BoxDecoration(
color: widget.backgroundColor,
border: Border.all(
color: widget.borderColor ?? widget.backgroundColor,
width: widget.borderWidth,
), borderRadius: BorderRadius.all(Radius.circular(4.0))
),
child: _getChild(),
),
ClipOval(
child:Image.network(url,width:100,height:100,fit:BoxFit.cover)
)
2. 给 Container 某一角设置圆角
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
),
),
),
2. CustomScrollView组件_Sliver组件
普通ListView无法嵌套ListView. 那么我们引入了CustomScrollView。
CustomScrollView是可以使用Sliver来自定义滚动模型(效果)的组件。它可以包含多种滚动模型,举个例子,假设有一个页面,顶部需要一个GridView,底部需要一个ListView,而要求整个页面的滑动效果是统一的,即它们看起来是一个整体。如果使用GridView+ListView来实现的话,就不能保证一致的滑动效果,因为它们的滚动效果是分离的,所以这时就需要一个"胶水",把这些彼此独立的可滚动组件"粘"起来,而CustomScrollView的功能就相当于“胶水”。
Sliver有细片、薄片之意,在Flutter中,Sliver通常指可滚动组件子元素(就像一个个薄片一样)。但是在CustomScrollView中,需要粘起来的可滚动组件就是CustomScrollView的Sliver了,如果直接将ListView、GridView作为CustomScrollView是不行的,因为它们本身是可滚动组件而并不是Sliver!因此,为了能让可滚动组件能和CustomScrollView配合使用,Flutter提供了一些可滚动组件的Sliver版,如SliverList、SliverGrid等。实际上Sliver版的可滚动组件和非Sliver版的可滚动组件最大的区别就是前者不包含滚动模型(自身不能再滚动),而后者包含滚动模型 ,也正因如此,CustomScrollView才可以将多个Sliver"粘"在一起,这些Sliver共用CustomScrollView的Scrollable,所以最终才实现了统一的滑动效果。
Sliver名称 | 功能 | 对应组件 | |
---|---|---|---|
SliverList | 列表 | ListView | |
SliverFixedExtentList | 项目高度固定列表 | ListView 指定itemExtent | |
SliverPrototypeExtentList | 根据原型生成高度固定的列表 | ListView 指定prototypeItem | |
SliverAnimatedList | 添加/删除列表项时执行动画 | AnimatedList | |
https://www.jianshu.com/p/d833103ac4e7
3. column中嵌套GridView 报一下错误
完整报错信息:
RenderFlex children have non-zero flex but incoming height constraints are unbounded.
When a column is in a parent that does not provide a finite height constraint, for example if it is in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining space in the vertical direction.
These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child cannot simultaneously expand to fit its parent.
解决办法:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
if (needGradeTag)
Padding(
padding: EdgeInsets.fromLTRB(15, 15, 0, 0),
child: Text(
"您的年级",
style: TextStyle(
color: Color(0xFF19191B),
fontSize: 17,
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(15, 15, 0, 0),
child: UnderlineText(
content: groupData.gradeTypeName,
textColor: Color(0xFF19191B),
textSize: 15,
),
),
GridView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, //横轴三个子widget
childAspectRatio: screenWidth / 3.0 / 38.0,
mainAxisSpacing: 4, crossAxisSpacing: 4
),
itemBuilder: (context, index) {
List<GradeVos> GradeList = groupData.gradeVos;
GradeVos gradeVos = GradeList[index];
return Container(
color: Colors.red,
child: Text("哈哈"),
);
},
itemCount: groupData.gradeVos.length,
),
],
),
column中添加 mainAxisSize: MainAxisSize.min,
4. 页面保存状态方法
class _SchoolState extends State<School> with AutomaticKeepAliveClientMixin
然后重写
@override
bool get wantKeepAlive => true;
5. 设置图片
1.image fit字段设置
Image.network("https://img.com",fit:BoxFit.fill)
BoxFit.fill:充满控件
BoxFit.cover:剪裁充满空间
BoxFit.fitWidth:宽度填充
BoxFit.fitHeight:高度填充
2. 平铺
repeat: ImageRepeat.repeatX x平铺
repeat: ImageRepeat.repeatY y平铺
repeat: ImageRepeat.repeat xy都平铺
6. card
shep: RounedRectangleBorder(
borderRadius:borderRadius.circle(10);
)
7. CirclrAvatar
CircleAvatar(
)
8. 按钮
9. Wrap
10. BottomNavgationBar
11. TabBar
12. flutter设置状态栏颜色
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
///状态栏颜色
class StatusBarDemoPage extends StatefulWidget {
const StatusBarDemoPage({super.key});
@override
_StatusBarDemoPageState createState() => _StatusBarDemoPageState();
}
class _StatusBarDemoPageState extends State<StatusBarDemoPage> {
bool customSystemUIOverlayStyle = false;
@override
Widget build(BuildContext context) {
var body = getBody();
///如果手动设置过状态栏,就不可以用 AnnotatedRegion ,会影响
if (customSystemUIOverlayStyle) {
return body;
}
///如果没有手动设置过状态栏,就可以用 AnnotatedRegion 直接嵌套显示
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.dark,
child: body,
);
}
getBody() {
return Scaffold(
appBar: const ImageAppBar(),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
TextButton(
onPressed: () {
///手动修改
setState(() {
customSystemUIOverlayStyle = true;
});
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle.light);
},
style: ButtonStyle(
backgroundColor: ButtonStyleButton.allOrNull<Color>(
Colors.yellowAccent,
),
),
child: const Text("Light"),
),
const SizedBox(
width: 10,
),
TextButton(
onPressed: () {
setState(() {
customSystemUIOverlayStyle = true;
});
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle.dark);
},
style: ButtonStyle(
backgroundColor: ButtonStyleButton.allOrNull<Color>(
Colors.greenAccent,
),
),
child: const Text("Dart"),
),
],
),
),
);
}
}
///自定义 PreferredSizeWidget 做 AppBar
class ImageAppBar extends StatelessWidget implements PreferredSizeWidget {
const ImageAppBar({super.key});
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Image.asset(
"static/gsy_cat.png",
fit: BoxFit.cover,
width: MediaQuery.sizeOf(context).width,
height: kToolbarHeight * 3,
),
SafeArea(
child: IconButton(
color: Colors.white,
icon: const Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.of(context).pop();
}),
)
],
);
}
@override
Size get preferredSize => const Size.fromHeight(kToolbarHeight * 3);
}
13. MediaQuery.viewInsetsOf(context).bottom 是用来获取当前应用的底部视图的内边距
viewInsets : 被系统用户界面完全遮挡的部分大小,简单来说就是键盘高度
14. 返回到根目录
Get.until((route) => route.settings.name == '/');
flutter 实现ios presnet效果
Get.to( widget, transition: Transition.downToUp);
15. 渐变色
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Container(
width: 200.0,
height: 200.0,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Colors.red,
Colors.blue,
],
),
),
),
),
),
);
}
}
16. NestedScrollView 的 headerSliverBuilder
headerSliverBuilder 中返回的数组中的widget只要是SliverToBoxAdapter包裹的就行
17. ListView去掉安全留白的方法
方法一:
ListView.builder(
padding: EdgeInsets.zero,
itemCount: 20,)
方法二:
MediaQuery.removePadding(context:context, removeTop: true,removeBottom: true, chail:)
18. 让某个widget在安全区域内
SafeArea(
child: Container(
height: 44,
color: Colors.blue,
))
19. 关于ExpansionTile
可通过shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0)),将展开边沿的黑线去掉