10 . 自定义控件
10.1 组合控件
10.2 自定义控件
- CustomPaint是用来承接自绘控件的容器,并不负责真正的绘制.
- 画布是canvas,画笔是Paint.
- 画成什么样子由CustomPainter来控制,将CustomPainter设置给容器CustomPaint的painter属性,我们就完成了一个自绘组件的封装
- Paint,其实和Android中的差不多,可以配置它的各种属性,比如颜色、样式、粗细等;而画布 Canvas,则提供了各种常见的绘制方法,比如画线 drawLine、画矩形 drawRect、画点 DrawPoint、画路径 drawPath、画圆 drawCircle、画圆弧 drawArc 等。
class WheelPainter extends CustomPainter {
Paint getColoredPaint(Color color) {
Paint paint = Paint();
paint.color = color;
return paint;
}
@override
void paint(Canvas canvas, Size size) {
//半径
double wheelSize = min(size.width, size.height) / 2;
//分成6份
double nbElem = 6;
//角度
double radius = (2 * pi) / nbElem;
//包裹饼图的矩形框 center:相对于原点的偏移量
Rect boundingRect = Rect.fromCircle(
center: Offset(wheelSize, wheelSize), radius: wheelSize);
//每次画1/6圆
canvas.drawArc(
boundingRect, 0, radius, true, getColoredPaint(Colors.orange));
canvas.drawArc(
boundingRect, radius, radius, true, getColoredPaint(Colors.green));
canvas.drawArc(
boundingRect, radius * 2, radius, true, getColoredPaint(Colors.red));
canvas.drawArc(
boundingRect, radius * 3, radius, true, getColoredPaint(Colors.blue));
canvas.drawArc(
boundingRect, radius * 4, radius, true, getColoredPaint(Colors.pink));
canvas.drawArc(boundingRect, radius * 5, radius, true,
getColoredPaint(Colors.deepOrange));
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
//判断是否需要重绘,简单做下比较
return oldDelegate != this;
}
}
class Cake extends StatelessWidget {
@override
Widget build(BuildContext context) {
//CustomPaint是用来承载自定义View的容器,需要自定义一个画笔,得继承自CustomPainter
return CustomPaint(
size: Size(200, 200),
painter: WheelPainter(),
);
}
}
11 . 主题定制
- 视觉效果是易变的,我们将这些变化的部分抽离出来,把提供不同视觉效果的资源和配置按照主题进行归类,整合到一个统一的中间层去管理,这样我们就能实现主题的管理和切换.
- Flutter中由ThemeData来统一管理主题的配置信息
- ThemeData中涵盖了Material Design规范的可自定义部分样式,比如应用明暗模式 brightness、应用主色调 primaryColor、应用次级色调 accentColor、文本字体 fontFamily、输入框光标颜色 cursorColor 等。
- 全局统一的视觉风格:
MaterialApp(
title: 'Flutter Demo',//标题
theme: ThemeData(//设置主题
brightness: Brightness.dark,//设置明暗模式为暗色
accentColor: Colors.black,//(按钮)Widget前景色为黑色
primaryColor: Colors.cyan,//主色调为青色
iconTheme:IconThemeData(color: Colors.yellow),//设置icon主题色为黄色
textTheme: TextTheme(body1: TextStyle(color: Colors.red))//设置文本颜色为红色
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
- 局部主题: 需要使用Theme来对App的主题进行局部覆盖,Theme是一个单子Widget容器,将控件放里面就可以控制主题了.
- 局部新建主题: 如果不想继承任何App全局的颜色或字体样式,可以直接新建一个ThemeData实例,依次设置对应的样式.
// 新建主题
Theme(
data: ThemeData(iconTheme: IconThemeData(color: Colors.red)),
child: Icon(Icons.favorite)
);
- 继承主题: 如果不想在局部重写所有的样式,则可以继承App的主题,使用copyWith方法,只更新部分样式
// 继承主题
Theme(
data: Theme.of(context).copyWith(iconTheme: IconThemeData(color: Colors.green)),
child: Icon(Icons.feedback)
);
Container(
color: Theme.of(context).primaryColor,//容器背景色复用应用主题色
child: Text(
'Text with a background color',
style: Theme.of(context).textTheme.title,//Text组件文本样式复用应用文本样式
));