写点什么

Agora Flutter SDK:一套代码,实现双端通话(二)

  • 2019-11-30
  • 本文字数:2586 字

    阅读完需:约 8 分钟

Agora Flutter SDK:一套代码,实现双端通话(二)

绿色部分为我们定义的 Stingy,红色小方块为 Stingy 的 child ,这里是一个 Container


代码中的输入如下 (iphone 6 尺寸):


flutter: constraints: BoxConstraints(100.0<=w<=375.0, 100.0<=h<=300.0)flutter: childParentData: offset=Offset(275.0, 200.0)flutter: size: Size(375.0, 300.0)
复制代码


上述我们自定义 RenderBox 的 performLayout() 中做的事情可大概分为如下三个步骤:


  • 使用 child.layout(…) 来布局 child,这里是为 child 根据 parent 传递过来的约束选择一个大小

  • child.parentData.offset , 这是在为 child 如何摆放设置一个偏移量

  • 设置当前 widget 的 size


在我们的例子中,Stingy 的 child 是一个 Container,并且 Container 没有 child,因此他会使用 child.layout(…) 中设置的最大约束。通常,每个 widget 都会以不同的方式来处理提供给他的约束。如果我们使用 RaiseButton 替换 Container:


Stingy(    child: RaisedButton(      child: Text('Button'),    onPressed: (){}  )  )
复制代码


效果如下:



可以看到,RaisedButton 的 width 使用了 parent 给他传递的约束值 100,但是高度很明显没有 100,RaisedButton 的高度默认为 48 ,由此可见 RaisedButton 内部对 parent 传递过来的约束做了一些处理。


我们上面的 Stingy 继承的是 SingleChildRenderObjectWidget,也就是只能有一个 child。那如果有多个 child 怎么办,不用担心,这里还有一个 MultiChildRenderObjectWidget,而这个类有一个子类叫做 CustomMultiChildLayout,我们直接用这个子类就好。


先来看看 CustomMultiChildLayout 的构造方法如下:


/// The [delegate] argument must not be null.
CustomMultiChildLayout({ Key key, @required this.delegate, List<Widget> children = const <Widget>[],})
复制代码


  • key:widget 的一个标记,可以起到标识符的作用

  • delegate:这个特别重要,注释上明确指出这个参数一定不能为空,我们在下会说

  • children:这个就很好理解了,他是一个 widget 数组,也就是我们们需要渲染的 widget


上面的 delegate 参数类型如下:


  /// The delegate that controls the layout of the children.  final MultiChildLayoutDelegate delegate;
复制代码


可以看出 delegate 的类型为 MultiChildLayoutDelegate,并且注释也说明了它的作用:控制 children 的布局。也就是说,我们的 CustomMultiChildLayout 里面要怎么布局,完全取决于我们自定义的 MultiChildLayoutDelegate 里面的实现。所以 MultiChildLayoutDelegate 中也会有类似的 performLayout(…) 方法。


另外,CustomMultiChildLayout 中的每个 child 必须使用 LayoutId 包裹,注释如下:


/// Each child must be wrapped in a [LayoutId] widget to identify the widget for  /// the delegate.
复制代码


LayoutId 的构造方法如下:


  /// Marks a child with a layout identifier.  /// Both the child and the id arguments must not be null.  LayoutId({    Key key,    @required this.id,        @required Widget child  })
复制代码


注释的大概意思说的是:使用一个布局标识来标识一个 child;参数 child 和 参数 id 不定不能为空。 我们在布局 child 的时候会根据 child 的 id 来布局。


下面我们来使用 CustomMultiChildLayout 实现一个用于展示热门标签的效果:


Container(   child: CustomMultiChildLayout(     delegate: _LabelDelegate(itemCount: items.length, childId: childId),     children: items,   ), )
复制代码


我们的 _LabelDelegate 里面接受两个参数,一个为 itemCount,还有是 childId。


_LabelDelegate 代码如下:


class _LabelDelegate extends MultiChildLayoutDelegate {  final int itemCount;  final String childId;    // x 方向上的偏移量  double dx = 0.0;    // y 方向上的偏移量  double dy = 0.0;
_LabelDelegate({@required this.itemCount, @required this.childId}); @override void performLayout(Size size) { // 获取父控件的 width double parentWidth = size.width; for (int i = 0; i < itemCount; i++) { // 获取子控件的 id String id = '${this.childId}$i'; // 验证该 childId 是否对应一个 非空的 child if (hasChild(id)) { // layout child 并获取该 child 的 size Size childSize = layoutChild(id, BoxConstraints.loose(size)); // 换行条件判断 if (parentWidth - dx < childSize.width) { dx = 0; dy += childSize.height; } // 根据 Offset 来放置 child positionChild(id, Offset(dx, dy)); dx += childSize.width; } } } /// 该方法用来判断重新 layout 的条件 @override bool shouldRelayout(_LabelDelegate oldDelegate) { return oldDelegate.itemCount != this.itemCount; }}
复制代码


在 _LabelDelegate 中,重写了 performLayout(…) 方法。方法中有一个参数 size,这个 size 表示的是当前 widget 的 parent 的 size,在我们这个例子中也就表示 Container 的 size。我们可以看看 performLayout(…)方法的注释:


  /// Override this method to lay out and position all children given this  /// widget's size.  ///  /// This method must call [layoutChild] for each child. It should also specify  /// the final position of each child with [positionChild].  void performLayout(Size size);
复制代码


还有一个是 hasChild(…) 方法,这个方法接受一个 childId,childId 是由我们自己规定的,这个方法的作用是判断当前的 childId 是否对应着一个非空的 child。


满足 hasChild(…) 之后,接着就是 layoutChild(…) 来布局 child , 这个方法中我们会传递两个参数,一个是 childId,另外一个是 child 的约束(Constraints),这个方法返回的是当前这个 child 的 Size。


布局完成之后,就是如何摆放的问题了,也就是上述代码中的 positionChild(…) 了,此方法接受一个 childId 和 一个当前 child 对应的 Offset,parent 会根据这个 Offset 来放置当前的 child。


最后我们重写了 shouldRelayout(…) 方法用于判断重新 Layout 的条件。


完整源码在文章末尾给出。


效果如下:


2 Flutter 和 Native 的交互

我们这里说的 Native 指的是 Android 平台。


2019-11-30 15:04735

评论

发布
暂无评论
发现更多内容

数据分析统计Minitab Express for Mac破解补丁 及安装教程 兼容m芯片

Rose

数据统计 Mac 软件 数据分析软件 Minitab Express下载 Minitab Express破解版

8月浙江省公安厅即将举办省网络与信息安全管理员项目职业技能竞赛

行云管家

网络安全 信息安全

巴赫:阿里AI技术将巴黎奥运转播带到新高度

阿里云CloudImagine

云计算 音视频 视频云 奥运会 AI增强技术

需求缺陷管理:8款最佳系统全面评测

爱吃小舅的鱼

缺陷管理系统 缺陷管理 缺陷管理工具 需求缺陷管理

低代码平台在采购管理中的革新与应用

天津汇柏科技有限公司

低代码 采购管理 软件定制开发

两个爆点,引爆在线教育平台数智化

字节跳动数据平台

在线教育 可视化 云服务 数智化

向量检索服务的基本概念

DashVector

向量检索 #数据库 #人工智能 #大模型

macos big sur 软件icons图标大全(新增至2719枚大苏尔风格图标)

Rose

ShareSDK第三方平台使用指南——新浪微博

MobTech袤博科技

Java 开发者 产品动态

第61期|GPTSecurity周报

云起无垠

深入解析 Go 语言 GMP 模型:并发编程的核心机制

王中阳Go

Go 面试 GMP

基于大模型的对话式数据分析产品“腾讯云 ChatBI ”正式上线公测

腾讯云大数据

腾讯云 BI

AlDente Pro :苹果电脑电池管理工具 延长电池寿命

Rose

苹果电脑 电池管理 AlDente Pro破解版 电池寿命

ETL数据集成丨将DB2数据同步至Postgres数仓实践

RestCloud

数据库 postgresql 数据同步 ETL 数据集成工具

利用 Python 和 IPIDEA:跨境电商与数据采集的完美解决方案

海拥(haiyong.site)

Python

微服务架构革新:百度Jarvis2.0与云原生技术的力量

百度Geek说

微服务架构 企业号2024年7月PK榜 百度商业产品矩阵 Jarvis应用托管平台

最佳实践分享 I 流程挖掘助力头部科技企业信创之路数字化转型

望繁信科技

数字化转型 降本增效 科技企业 流程挖掘 望繁信科技

超13万律师使用的工具,启信宝推出“司法大数据”功能

合合技术团队

人工智能 大数据 司法

复古传奇,经典归来,清渊传奇详细图文架设教程

echeverra

清渊传奇

Autodesk AutoCAD2020(附安装教程图解) 激活特别版 mac/win

Rose

AutoCAD2022序列号 autocad2022秘钥

Databend 开源周报第 155 期

Databend

支持英文语言的堡垒机是什么?叫做什么名字?

行云管家

软件 堡垒机

油猴Safari浏览器辅助插件 油猴脚本Tampermonkey mac版下载安装教程

Rose

Tampermonkey插件 油猴脚本使用

综合性价比超越硅谷,PPIO派欧云发布下一代推理加速引擎

Geek_2d6073

日程管理多源归一,服务场景一键直达

HarmonyOS SDK

HarmonyOS

Interconnectivity of Industrial Equipment: IPQ9574 vs. IPQ4019 in Real-World Applications

wallyslilly

IPQ5332 WiFi 7 Router with QCN9274-6G and QCN9274-5G Modules: A Comprehensive Technical Analysis

wifi6-yiyi

WiFi7

React 的 KeepAlive 实战指南:深度解析组件缓存机制

袋鼠云数栈

前端 技术人 UED keepalive keep-alive实现原理

Pod 卡在 Terminating 怎么办?

小猿姐

Kubernetes kubernetes pod

硅纪元视角 | 苹果AI训练数据大曝光,坚持用户隐私第一

硅纪元

推荐5款人事管理系统!免费可用

软件大师兄

草料二维码 人事管理系统 简道云

Agora Flutter SDK:一套代码,实现双端通话(二)_文化 & 方法_声网_InfoQ精选文章