赵走x博客
网站访问量:151879
首页
书籍
软件
工具
古诗词
搜索
登录
75、插件开发:iOS端API实现
64、文件操作
85、图片加载原理与缓存
84、Flutter运行机制-从启动到显示
83、RenderObject和RenderBox
82、Element与BuildContext
81、Flutter UI系统
80、国际化常见问题
79、使用Intl包
78、实现Localizations
77、让App支持多语言
76、Texture和PlatformView
73、开发Flutter插件
72、插件开发:平台通道简介
71、开发Package
70、Json转Dart Model类
69、使用Socket API
68、使用WebSockets
67、实例:Http分块下载
66、Http请求-Dio http库
65、通过HttpClient发起HTTP请求
63、自绘实例:圆形背景渐变进度条
62、自绘组件 (CustomPaint与Canvas)
61、组合实例:TurnBox
60、组合现有组件
59、自定义组件方法简介
58、动画过渡组件
57、通用"切换动画"组件(AnimatedSwitcher)
56、交织动画
55、Hero动画
54、自定义路由切换动画
53、动画基本结构及状态监听
51、动画
50、通知(Notification)
49、全局事件总线
48、手势识别
47、原始指针事件处理
46、事件处理与通知
45、对话框详解
44、异步UI更新(FutureBuilder、StreamBuilder)
43、颜色和主题
42、跨组件状态共享(Provider)
41、数据共享(InheritedWidget)
40、导航返回拦截(WillPopScope)
39、功能型Widget简介
38、滚动监听及控制
37、CustomScrollView
36、GridView
35、ListView
34、SingleChildScrollView
33、可滚动组件简介
32、剪裁(Clip)
31、Scaffold、TabBar、底部导航
30、Container
29、变换(Transform)
28、装饰容器DecoratedBox
27、尺寸限制类容器
26、填充(Padding)
25、容器类Widget
24、对齐与相对定位(Align)
23、层叠布局 Stack、Positioned
22、流式布局
21、弹性布局(Flex)
20、线性布局(Row和Column)
19、布局类组件简介
18、进度指示器
17、输入框及表单
16、单选开关和复选框
15、图片及ICON
14、按钮
13、文本、字体样式
12、状态管理
11、Widget简介
10、Flutter异常捕获
9、调试Flutter应用
8、资源管理
7、包管理
6、路由管理
5、第一个Flutter应该:计数器应用示例
4、Dart语言简介
3、搭建Flutter开发环境
2、初识Flutter
1、移动开发技术简介
59、自定义组件方法简介
资源编号:76211
Flutter实战
书籍
热度:75
当Flutter提供的现有组件无法满足我们的需求,或者我们为了共享代码需要封装一些通用组件,这时我们就需要自定义组件。在Flutter中自定义组件有三种方式:通过组合其它组件、自绘和实现RenderObject。本节我们先分别介绍一下这三种方式的特点,后面章节中则详细介绍它们的细节。
当Flutter提供的现有组件无法满足我们的需求,或者我们为了共享代码需要封装一些通用组件,这时我们就需要自定义组件。在Flutter中自定义组件有三种方式:通过组合其它组件、自绘和实现RenderObject。本节我们先分别介绍一下这三种方式的特点,后面章节中则详细介绍它们的细节。 # 组合其它Widget 这种方式是通过拼装其它组件来组合成一个新的组件。例如我们之前介绍的Container就是一个组合组件,它是由DecoratedBox、ConstrainedBox、Transform、Padding、Align等组件组成。 在Flutter中,组合的思想非常重要,Flutter提供了非常多的基础组件,而我们的界面开发其实就是按照需要组合这些组件来实现各种不同的布局而已。 # 自绘 如果遇到无法通过现有的组件来实现需要的UI时,我们可以通过自绘组件的方式来实现,例如我们需要一个颜色渐变的圆形进度条,而Flutter提供的CircularProgressIndicator并不支持在显示精确进度时对进度条应用渐变色(其valueColor 属性只支持执行旋转动画时变化Indicator的颜色),这时最好的方法就是通过自定义组件来绘制出我们期望的外观。我们可以通过Flutter中提供的CustomPaint和Canvas来实现UI自绘。 # 实现RenderObject Flutter提供的自身具有UI外观的组件,如文本Text、Image都是通过相应的RenderObject(我们将在“Flutter核心原理”一章中详细介绍RenderObject)渲染出来的,如Text是由RenderParagraph渲染;而Image是由RenderImage渲染。RenderObject是一个抽象类,它定义了一个抽象方法paint(...): ``` void paint(PaintingContext context, Offset offset) ``` PaintingContext代表组件的绘制上下文,通过PaintingContext.canvas可以获得Canvas,而绘制逻辑主要是通过Canvas API来实现。子类需要重写此方法以实现自身的绘制逻辑,如RenderParagraph需要实现文本绘制逻辑,而RenderImage需要实现图片绘制逻辑。 可以发现,RenderObject中最终也是通过Canvas API来绘制的,那么通过实现RenderObject的方式和上面介绍的通过CustomPaint和Canvas自绘的方式有什么区别?其实答案很简单,CustomPaint只是为了方便开发者封装的一个代理类,它直接继承自SingleChildRenderObjectWidget,通过RenderCustomPaint的paint方法将Canvas和画笔Painter(需要开发者实现,后面章节介绍)连接起来实现了最终的绘制(绘制逻辑在Painter中)。 # 总结 “组合”是自定义组件最简单的方法,在任何需要自定义组件的场景下,我们都应该优先考虑是否能够通过组合来实现。而自绘和通过实现RenderObject的方法本质上是一样的,都需要开发者调用Canvas API手动去绘制UI,优点是强大灵活,理论上可以实现任何外观的UI,而缺点是必须了解Canvas API细节,并且得自己去实现绘制逻辑。 在本章接下来的小节中,我们将通过一些实例来详细介绍自定义UI的过程,由于后两种方法本质是相同的,并且Flutter中很多基础组件都是通过RenderObject的形式来实现的,所以后续我们只介绍CustomPaint和Canvas的方式,读者如果对自定义RenderObject的方法好奇,可以查看Flutter中相关基础组件对应的RenderObject的实现源码,如RenderParagraph或RenderImage。