一统天下 flutter
Posted webabcd - 专注于 flutter, android
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一统天下 flutter相关的知识,希望对你有一定的参考价值。
一统天下 flutter https://github.com/webabcd/flutter_demo
作者 webabcd
一统天下 flutter - widget 列表类: GridView - 网格
示例如下:
lib\\widget\\list\\grid_view.dart
/*
* GridView - 网格
*/
import \'dart:math\';
import \'package:flutter/material.dart\';
import \'../../helper.dart\';
class GridViewDemo extends StatefulWidget
const GridViewDemo(Key? key) : super(key: key);
@override
_GridViewDemoState createState() => _GridViewDemoState();
class _GridViewDemoState extends State<GridViewDemo>
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(title: const Text("title")),
backgroundColor: Colors.orange,
body: Column(
children: [
/// GridView.count()
Expanded(child: _Demo1(),),
/// GridView.builder() 结合 SliverGridDelegateWithFixedCrossAxisCount()
Expanded(child: _Demo2(),),
/// GridView.builder() 结合 SliverGridDelegateWithMaxCrossAxisExtent()
Expanded(child: _Demo3(),),
],
),
);
class _Demo1 extends StatelessWidget
@override
Widget build(BuildContext context)
/// GridView.count() - 用于创建一个有固定数量元素的网格
return GridView.count(
/// 滚动方向 vertical 或 horizontal
scrollDirection: Axis.vertical,
/// 非滚动方向上的元素数量
crossAxisCount: 3,
/// 滚动方向上的元素之间的间距
mainAxisSpacing: 10,
/// 非滚动方向上的元素之间的间距
crossAxisSpacing: 10,
/// 网格控件本身的内间距
padding: const EdgeInsets.all(10),
/// 举例说明,如果网格是垂直滚动的话
/// 那么横向排列的元素的数量是确定的,也就是说元素的宽度是确定的,然后通过这个参数指定宽和高的比值,从而确定元素的高度
childAspectRatio: 2,
/// 用于控制滚动的 ScrollController
controller: null,
/// 下面这 3 个参数的用法和 ListView 是一样的,参见 list_view.dart
physics: const AlwaysScrollableScrollPhysics(),
addAutomaticKeepAlives: true,
addRepaintBoundaries: true,
/// 组件集合
children: [
Container(color: Colors.red[100],),
Container(color: Colors.red[200],),
Container(color: Colors.red[300],),
Container(color: Colors.red[400],),
Container(color: Colors.red[500],),
Container(color: Colors.green[100],),
Container(color: Colors.green[200],),
Container(color: Colors.green[300],),
Container(color: Colors.green[400],),
Container(color: Colors.green[500],),
Container(color: Colors.blue[100],),
Container(color: Colors.blue[200],),
Container(color: Colors.blue[300],),
Container(color: Colors.blue[400],),
Container(color: Colors.blue[500],),
],
);
class _Demo2 extends StatelessWidget
final Random _random = Random();
late final List<_MyModel> _myList;
_Demo2(Key? key) : super(key: key)
_myList = [for (var i = 0; i < 50; i++) _MyModel(name: "webabcd: $i", age: _random.nextInt(100))];
Widget _getItem(BuildContext context, int index)
return Container(
color: Colors.red,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MyTextSmall(_myList[index].name),
MyTextSmall(_myList[index].age.toString()),
],
),
);
@override
Widget build(BuildContext context)
/// GridView.builder() - 根据数据源动态生成对应的网格元素
return GridView.builder(
/// SliverGridDelegateWithFixedCrossAxisCount() - 用于指定非滚动方向上的元素的数量
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
/// 非滚动方向上的元素的数量
crossAxisCount: 3,
/// 滚动方向上的元素之间的间距
mainAxisSpacing: 10,
/// 非滚动方向上的元素之间的间距
crossAxisSpacing: 10,
/// 滚动方向上的元素的长度(垂直滚动则此参数用于指定网格内元素的高度;水平滚动则此参数用于指定网格内元素的宽度)
mainAxisExtent: 150,
/// 如果不指定 mainAxisExtent 则以 childAspectRatio 为准,关于 childAspectRatio 的说明上面已经讲过了
/// childAspectRatio: 1,
),
/// 滚动方向 vertical 或 horizontal
scrollDirection: Axis.vertical,
/// 网格控件本身的内间距
padding: const EdgeInsets.all(10),
/// 用于指定网格中的元素数量
itemCount: _myList.length,
/// 用于构造网格中的每个元素
itemBuilder: _getItem,
);
class _Demo3 extends StatelessWidget
final Random _random = Random();
late final List<_MyModel> _myList;
_Demo3(Key? key) : super(key: key)
_myList = [for (var i = 0; i < 50; i++) _MyModel(name: "webabcd: $i", age: _random.nextInt(100))];
Widget _getItem(BuildContext context, int index)
return Container(
color: Colors.green,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MyTextSmall(_myList[index].name),
MyTextSmall(_myList[index].age.toString()),
],
),
);
@override
Widget build(BuildContext context)
/// GridView.builder() - 根据数据源动态生成对应的网格元素
return GridView.builder(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
/// 非滚动方向上的元素的最大长度
/// 比如垂直滚动时,此参数用于指定水平方向上的元素的最大宽度,然后 GridView 会按此要求最终给元素一个合适的宽度
maxCrossAxisExtent: 100,
/// 滚动方向上的元素之间的间距
mainAxisSpacing: 10,
/// 非滚动方向上的元素之间的间距
crossAxisSpacing: 10,
/// 滚动方向上的元素的长度(垂直滚动则此参数用于指定网格内元素的高度;水平滚动则此参数用于指定网格内元素的宽度)
mainAxisExtent: 150,
/// 如果不指定 mainAxisExtent 则以 childAspectRatio 为准,关于 childAspectRatio 的说明上面已经讲过了
/// childAspectRatio: 1,
),
/// 滚动方向 vertical 或 horizontal
scrollDirection: Axis.vertical,
/// 网格控件本身的内间距
padding: const EdgeInsets.all(10),
/// 用于指定网格中的元素数量
itemCount: _myList.length,
/// 用于构造网格中的每个元素
itemBuilder: _getItem,
);
class _MyModel
const _MyModel(required this.name, required this.age);
final String name;
final int age;
一统天下 flutter https://github.com/webabcd/flutter_demo
作者 webabcd
WeexRN还是Flutter?聊聊阿里跨平台开发框架选型思路
作者 | 黄刚(腾渊)
策划 | Kitty
随着移动互联网的发展,Android 和 iOS 呈两分天下之势,跨平台开发也逐渐成为移动领域的热门话题之一。怎么看待其背后的发展逻辑?跨平台开发的难点是什么?未来的发展方向如何?近日,InfoQ 有幸约到阿里巴巴淘系技术部资深无线技术专家黄刚(花名:腾渊),请他介绍跨平台开发的发展趋势和变化。
腾渊认为:从早期比较流行的 Hybrid App,到后来的 React Native、Weex,再到现在比较火爆的小程序和 Flutter,可以看到跨平台的发展趋势是框架变得越来越重。如果当前的业务情况下前台呈现比较不稳定并且整个前台开发占比较高,那么应用跨平台框架的收益就比较高了。到底哪个方向更正确、哪个框架更好其实是没有标准答案的,更多需要开发者因时制宜地选择。
他还会在即将召开的 QCon 全球软件开发大会 2020(北京站)上担任「移动新生态趋势下的应用实践」专题的出品人,感兴趣的读者可以关注。以下为黄刚(腾渊)的观点精华。
在移动互联网时代,当 Android 和 iOS 奠定了整个移动 OS 的地位后,跨平台研发就一直是一个大的研究方向或者说大的课题。这个话题其实很有意思,因为很多时候大家会有些默认的假设,比较容易忽视这个方向出现或者变热的前提条件。
从 PC 时代开始,就有一些像 Qt 之类的非常优秀的跨平台软件研发框架。但是我们回过头来看,那个时候面向个人用户的跨平台研发很难说是一个非常热的方向,其中最主要的原因就在于 PC 时代 Windows 的绝对统治地位。假设今天我们在移动互联网上只有一个 OS 占绝对统治地位,那可能今天也不太会有业界同仁在研究跨平台研发这个事情了,这是一个大的前提。
在移动时代,在 Android、iOS 作为移动 OS 双巨头的格局下,天然就会带来一个重复开发导致移动应用开发成本增大的问题。要开发一个应用,服务端、前端都可以是一套班子,客户端基本需要 Android 和 iOS 两套开发班子,所以不难理解跨平台研发这个话题的起点在于降低研发成本。在这个基本问题下,往下衍生的问题就是多平台的开发增加的额外成本到底是多少,在整个研发生命周期中的占比是多少,跨平台的开发框架能多大程度上解决这个问题?只有这个问题回答清楚了,我们才能明确适合自己的跨平台开发框架应该具备哪些特征,这个跨平台框架在一个 App 应用中的使用范围是多大。
从早期比较流行的 Hybrid App 到后来的 React Native、Weex,再到现在比较火爆的小程序和 Flutter,可以看到跨平台研发框架变得越来越重。是不是一定越重、越新的框架越好?答案是不一定。
从应用的 Life Cycle 来看,研发阶段只是其中一个阶段,是否具有长久的可维护性、可运维性也是需要重点考虑的问题。再到研发阶段本身,整个研发是从前端到后端 End-to-End 的,跨平台更多地是集中在大前端领域内的话题,如果在当下的业务形态里,前台展现是高度产品化、比较稳定或者对于性能以及交互的要求极度苛刻的,那么 Cross-Platform First 未必是一个理想的选择。
一方面是多平台开发工作在整个研发成本里的占比不高,ROI 未必高;另一方面是 Cross-Platform First 是以牺牲平台特性为代价来达到跨平台的一致性(本质上跨平台研发框架也基本无法做到多平台上表现得完全一致性)。在达到一致性表现的过程中,工程上的填坑成本可能更高。
反过来讲,如果当前的业务情况下,前台的呈现比较不稳定并且整个前台开发占比较高,那么应用跨平台框架的收益就比较高了,在阿里比较典型的例子就是 Weex 在大促会场上的应用。
我们都应该理解,从 Hybrid 的方案到 React Native、Weex 再到 Flutter,本质上都是在研发成本、灵活性、性能体验三者间找一个平衡点,只是大家切入的点不太一样,最终导致整个解决方案有了不同。假设说现在你要做一个新的 App,可能整个开发团队是多前端、少客户端的,那么我可能会比较建议大家多考虑 Hybrid 的模式;如果对性能要求比较高,就可以考虑用用 Weex 或者 React Native;反过来,如果是客户端同学比较多,那么考虑下 Flutter 未尝不可。
其实我们也可以看到,像 Google 同时在推 Flutter 和 Kotlin,这两个东西本质是不一样的,Flutter 更多地体现 Cross-Platform First,Kotlin 更多地体现 Platform First,到底哪个方向更正确,哪个框架更好,其实是没有标准答案的,更多需要开发者因时制宜地进行选择。
当下阿里用的比较多的应该是 Weex、DinamicX 和小程序这几个框架,在不同场景下解决不同的核心问题。任何框架都不能脱离当时发展的背景讨论,这几个框架是因为在不同阶段解决了当时手淘的一些核心问题,所以才能在各条业务线上广泛应用。
我们从 2015 年开始做 Weex,2016 年大规模应用。当时我们大促会场页面从研发效率以及发布的灵活性考虑,统一使用的是 H5,但在当时,性能和体验都有些问题。同样,当时手淘上众多的导购业务因为很难接受 H5 的性能与体验,强烈要求使用 Native 做页面开发,这样就又带来了另外一个问题,即 App 的包大小的问题。Weex 在这个背景下诞生,在尽量保留 H5 研发效率以及部署灵活性的前提下,尽量提升页面的性能体验。
不难想象,在这种情况下,我们整个开发框架必然是面向前端、全面兼容 H5 的研发模式。当然其中 Vue 和 Rax 这样的前端框架也是功不可没的。因为 Weex 的出现,大幅度提高了当时会场页面的性能,而且满足了大部分导购频道对于性能的要求。导购业务在性能基础体验能够满足的情况下,其实很多导购业务还是倾向于更灵活的研发与部署模式,所以当时很多的导购业务还从 Native 转回到了 Weex 进行开发,间接帮助了手淘 App 包大小的控制。
我们从 2017 年开始做 DinamicX,2018 年大规模应用。这个框架的诞生就要顺着刚才的历史接着往下讲。Weex 解决了原先使用 H5 的业务的性能诉求,但是我们发现 Weex 在一些产品化程度很高的业务域内,依然不能满足性能要求,比如说首页这类一级 Tab 页,所以这种业务基本都还是保留了 Native 的开发模式。
虽然 Native 的开发模式被保留了下来,但是不意味着这些业务对于开发的平台一致性、研发效率、部署效率没有要求。为了解决这些问题,DinamicX 使用了类似于 Android layout 的声明式布局。相较于 Weex,DinamicX 并没有引入脚本引擎的能力,通过牺牲部分灵活性,来达到性能的极致。通过这样的方式,能够做到在性能基本和 Native 开发持平的情况下,比较灵活地调整页面布局,再通过和我们内部的新奥创研发平台的结合,实现页面布局与业务逻辑的分离。通过这样的方式,DinamicX 这个框架基本解决了我们在基础产品业务域内的研发效率以及性能体验的平衡问题。
再来讲讲小程序框架,现在我们更多地是使用在了商家应用场景上,核心是为了解决我们在集团多个 App 之间业务快速部署以及外部商家开发的页面快速入驻手淘并且能够得到有效管控的问题。小程序最近比较热,这个点上我就不展开了。
至于 Flutter,我们内部使用比较深入的是闲鱼的同学。对于跨平台领域的解决方案,我不太秉持只有一个正确答案的想法,对于终极解决方案这个结论我还是比较存疑的,但有一个需要探索的重要方向是可以确定的:决定一个跨平台解决方案的成败有两个重要因素,一个是技术产品化程度,或者说是工程化水平;另外一个是整个开发者生态的构建。如果从这两个因素来看的话,可以明确都还有一段很长的路要走。手淘今年也成立了专门的团队在研究 Flutter 的应用,我们可以拭目以待。
5G 也是大家非常关注的热点,我们内部的讨论也会比较多。毫无疑问,5G 将能带来一些爆点场景,但是这方面的预测是相当困难的。现在市面上关于 AR/VR 和多媒体应用的畅想理论上都没有什么问题,但是从商业的角度来讲,我们还不知道整个变化对于成本方面的影响,而成本的考量对于应用场景是极其重要的。
我举个简单的例子,很多 App 在视频自动播放下都有一个设置选项,叫做“Wi-Fi 下自动播放”,绝大多数 App 在使用移动流量播放流媒体之前一般都会给用户弹一个提醒,“当前在用移动流量播放,可能会产生资费”。大家想一想,这个背后的本质是不是就是关于成本的考量。这个限制其实对于整个应用的场景影响是非常大的,正如 4G 的流量费用大幅降低让移动互联网走到了亿万用户手中,5G 的使用成本将极大影响它的使用场景。但是我们依然可以做一个大胆的预测,当 5G 帮助大家极大突破了网络传输速率的束缚后,后面紧接而来的可能是对终端设备算力大幅提升的诉求,最后才创造出一个个崭新的应用场景,这是一个从网络到终端设备到应用场景整体升级的过程。
我个人最近比较关注 On-Device AI 的应用实践,如果说跨平台解决的是节约研发成本的问题,On-Device AI 的应用是真正会产生业务增量的技术新赛道。过去的一年中,在 On-Device AI 上手淘有了比较大规模的应用,一个典型的场景就是信息流这个商品、内容等的混合智能推荐场景。我们通过更低的资源消耗、更多的数据输入、更实时的感知,在整个信息流场景导购侧有了非常大幅度的提升。过去一年的实践只是一个开端,我们齐头并进的应用场景还包括 AR 美妆、消息 Push、直播等等,这块的想象空间是非常大的。
黄刚(腾渊) 阿里巴巴淘系技术部资深无线技术专家,现淘系技术部基础链路负责人,负责首页、商品详情、交易、信息流等核心业务。2014 年加入阿里巴巴,2018 年双十一淘宝技术部技术队长,2019 年淘系技术部技术队长。
【InfoQ Pro 上线啦!】作为 InfoQ 中文站的移动端入口,这里有深度专业的技术内容,独家报道的技术实践,专属 InfoQ Pro 会员的福利优惠!扫码关注,免费领取 InfoQ 独家节目《大咖说》全套视频,围观成功人士对技术的理解!
Flutter 作为革命性的跨终端解决方案,一经推出就获得了广泛关注。新的一年,Flutter 在原有的工程效率和体验侧有什么新的变化?在业务对用户增长和游戏化诉求强烈的今天,Flutter 带来的想象力是什么?Flutter 未来的机会和挑战是什么?GMTC 全球大前端技术大会(北京站)2020 设置“Flutter 实战“专场,希望通过一线的实际解决方案,带给大家新的思考和借鉴。
大会 7 折购票,限时立减 1440 元,团购会更加优惠哦!联系票务经理鱼丸:13269078023(同微信)
可以扫描下图二维码或者点击【阅读原文】,查看官网了解更多详情!
以上是关于一统天下 flutter的主要内容,如果未能解决你的问题,请参考以下文章