Wigets学习之Cell(自实现)
时间:2021-07-01 02:46:41
Flutter
没有Cell(单元格)
部件,所以接下来自实现两个部件:CellGroup
、Cell
cell.dart
import 'package:flutter/material.dart';
// 数据共享
class _Provider extends InheritedWidget {
_Provider({required Widget child, required this.data}) : super(child: child);
final dynamic data;
static of(BuildContext context) {
return context.getElementForInheritedWidgetOfExactType<_Provider>()?.widget;
}
@override
bool updateShouldNotify(covariant InheritedWidget oldWidget) => false;
}
class CellGroup extends StatelessWidget {
const CellGroup(
{Key? key, required this.children, this.title, this.isBorder = true})
: super(key: key);
// 单元格列表
final List<Cell> children;
// 单元格组标题
final String? title;
// 单元格是否显示底部边框
final bool? isBorder;
@override
Widget build(BuildContext context) {
final List<Widget> list = [];
if (title != null) {
list.add(Padding(
padding: EdgeInsets.symmetric(vertical: 8),
child: Text(
title!,
style: TextStyle(color: Colors.black26),
),
));
}
list.addAll(children);
return _Provider(
data: {
'isBorder': isBorder,
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: list,
),
);
}
}
const defaultRightIcon = const Icon(
Icons.arrow_forward_ios,
color: Colors.black26,
size: 20,
);
class Cell extends StatelessWidget {
const Cell(
{Key? key,
this.icon,
required this.title,
this.subTitle,
this.rightIcon = defaultRightIcon,
this.color = Colors.white,
this.titleColor = Colors.black,
this.titleStyle,
this.subTitleColor = Colors.black26,
this.subTitleStyle,
this.height = 48,
this.horizontalPadding = 12,
this.isBorder})
: super(key: key);
// 左侧图标
final Widget? icon;
// 标题
final String title;
// 副标题
final String? subTitle;
// 右侧图标,默认为右箭头
final Icon? rightIcon;
// 背景色
final Color? color;
// 标题颜色
final Color? titleColor;
// 标题样式
final TextStyle? titleStyle;
// 副标题颜色
final Color? subTitleColor;
// 副标题样式
final TextStyle? subTitleStyle;
// 高度
final double? height;
// 两侧边距
final double? horizontalPadding;
// 是否显示border
final bool? isBorder;
@override
Widget build(BuildContext context) {
final List<Widget> list = [];
if (icon != null) {
list.add(icon!);
}
final Text titleWidget = Text(
title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: titleStyle != null ? titleStyle : TextStyle(color: titleColor),
);
final List<Widget> titleList = [titleWidget];
if (subTitle != null) {
titleList.add(Text(
subTitle!,
style: subTitleStyle != null
? subTitleStyle
: TextStyle(color: subTitleColor),
overflow: TextOverflow.ellipsis,
));
}
list.add(Expanded(
child: Container(
padding: EdgeInsets.only(left: 8),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: titleList,
),
),
));
list.add(rightIcon!);
dynamic provider = _Provider?.of(context);
// isBorder存在则使用isBorder,否则判断CellGroup.isBorder存在,则用CellGroup.isBorder,否则为true
bool borderVisible = isBorder ?? provider?.data['isBorder'] ?? true;
return Container(
height: height! < 48 ? 48 : height,
decoration: borderVisible
? BoxDecoration(
color: color,
border: Border(bottom: BorderSide(color: Colors.black12)))
: null,
padding: EdgeInsets.symmetric(horizontal: horizontalPadding!),
child: Row(
children: list,
),
);
}
}
CellGroup
单元格组,用于包裹单元格
children
:单元格列表(必填),类型是List<Cell>
title
:单元格组标题isBorder
:单元格是否显示底部边框
Cell
icon
:左侧图标title
:标题subTitle
:副标题rightIcon
:右侧图标,默认为Icons.arrow_forward_ios
color
:背景色titleColor
:标题颜色titleStyle
:标题样式subTitleColor
:副标题颜色subTitleStyle
:副标题样式height
:高度,默认为 48 且最小为 48horizontalPadding
:两侧边距,默认为 12isBorder
:是否显示底部边框
import 'package:flutter/material.dart';
import 'package:learn/widgets/cell.dart';
void main() {
runApp(App());
}
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '自实现Cell',
home: Scaffold(
appBar: AppBar(
title: Text('自实现Cell'),
),
body: Padding(
padding: EdgeInsets.all(12),
child: CellGroup(
title: '标题',
children: [
Cell(
icon: Icon(Icons.mail),
title: '邮件',
),
Cell(
icon: Icon(Icons.message),
title: '消息通知',
)
],
),
),
),
);
}
}