上一篇介绍Banner的开发。在大多数应用场景中。banner和ListView通常是一起显示的。 并且能够共同滑动。例如如下界面:
创新互联主要从事成都做网站、网站建设、网页设计、企业做网站、公司建网站等业务。立足成都服务四川,十多年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18982081108
要实现上图的界面,直接想到是ListView添加Header。但在Flutter中,ListView 组件相当于RecyclerView,所以添加Header也用RecyclerView的原理:
封装ListPage组件,list_page.dart
使用及测试:异步加载网络数据使用
注意: 滚动组件添加: physics: ClampingScrollPhysics() 可以处理IOS系统的物理滚动的效果(即橡皮筋效果)
ListView 是最常用的可滚动组件之一,可以沿一个方向线性排布所有子组件,并且它也支持基于Sliver的延迟构建模型
默认构造函数:
ListView.builder:
ListView.separated:
ListView.separated 可以在生成的列表项之间添加一个分割组件,它比 ListView.builder 多了一个 separatorBuilder 参数,该参数是一个分割组件生成器。
RefreshIndicator 下拉刷新:
RefreshIndicator 是 Material 风格的下拉刷新组件。
CupertinoSliverRefreshControl 下拉刷新:
CupertinoSliverRefreshControl 是 ios 风格的下拉刷新控件。
上拉加载的功能,需要用到 ScrollController + ListView组件:
为了提升用户体验,使用三方登录APP的功能怎么能少呢,但是苹果的AppStore有一个很变态的要求,接入其他三方登录的话,要求必须也要接入苹果登录。面对这么变态的要求,作为一个有实力的码农怎么能拒绝呢!
下面为大家介绍一个好用的Flutter插件 Sign in With Apple ,可以帮助我们快速的接入苹果账号功能,插件的英文文档讲的比较详细了,英文好的同学可以直接参阅英文文档集成。
在项目的 pubspec.yaml 文件中添加sign_in_with_apple插件的依赖,如果您使用的Flutter SDK 1.x版本请添加依赖版本 2.5.4 :
如果您使用的Flutter SDK为2.x,请使用最新版本,当前最新版本 3.0.0
使用XCode打开项目后,按照以下图片上的步骤添加 Sign in With Apple Capabilities:
成功添加 Sign in With Apple能力后,可以在下面的列表中就代表添加成功了,如下图:
讲道理我起的好长的名字啊,不过文如上题,搜索到这里的兄弟应该都知道我说的是啥情况,正好
~~
我这个方案可能有点笨拙TT,不过自测有效,有其它想法的老哥希望可以帮忙指点一下~
下面进入正题
点进源码里面看,可以发现他直接继承了StatelessWidget,那我们就直接看看build方法
可以看到,这里直接返回一个scrollable或者一个子节点是scrollable的InheritedWidget
scrollable是一个StatefulWidget,那我们就看看它的state
首先scrollable持有一个scrollposition对象,是通过其scrollcontroller构建的
在其state的setCanDrag方法中,对其拖动设置了一系列的监听
这里就可以看出来,当拖动触发时,就会通过当前scrollable的position生成一个Drag/Hold对象,并调用相应的方法 这个position有几个子类,我们先随便看一个实现
可以看到生成了一个ScrollDragController对象,当手势拖动而调用这个对象的update方法时
可以看到直接调用其委托对象的applyUserOffset方法进行偏移,而这个委托对象根据刚才的drag方法可以得知正是我们scrollable中的position
最后,由position通知其scrollcontext,也就是之前的scrollable进行滑动
具体的滑动流程这里就不细说了,我们只是要知道这个事件是怎么传递的就好了,有兴趣的老哥可以自行分析
NestedScrollView是一个statefulwidget,那我们就先看看它的build方法
先忽略其他奇奇怪怪的方法,我们发现在我们body的外面,包裹了一层PrimaryScrollController,同时它还持有innerController,这个innerController暂时先不管它是啥
还记不记得在最开始ScrollView的build方法中,生成Scrollable的时候,我们已经见过这个PrimaryScrollController了,再回顾一下
再看看PrimaryScrollController.of(context)
可以看到,在生成scrollable的时候,在primary = true的情况下是会向上查找的,看看有没有PrimaryScrollController,如果有的话,scrollable使用的controller实际就是nestedscrollview中的innerController了
而之前看过了,scrollable中的position就是scrollcontroller来生成的,那么在这种情况下:
实际上是生成了_NestedScrollPosition并返回给了body中的scrollable
构造方法中有一个参数coordinator 暂时先不管
好了,下面我们在回头看刚才NestedScrollView的build方法,实际上是生成了一个_NestedScrollViewCustomScrollView,继承自大名鼎鼎的CustomScrollView,它当然也是scrollview啦,而我们传给它的controller也是一个_NestedScrollController,不过叫做_outerController,和body中的不是同一个罢了,那么自然这个父scrollview的position也是_NestedScrollPosition。
下面我们按照之前的逻辑,当拖动开始时,就会调用position.drag方法
可以看到,实际上吧方法交给了我们之前多次见到的coordinator来完成,那我们就简单看一下吧
这里可以看到,他把返回的ScrollDragController的委托者设成了自己
那么自然在拖动的时候,调用的就是coordinator的applyUseroffset方法了 我们分析一下
可以看到,在需要子列表滚动时,是对innerPositions中的所有position调用滑动方法的
而这innerPositions中的position是怎么来的呢?跟踪一下可以发现是在调用NestedScrollController的attach时添加进来的,如下
因为之前我们看到过,子scrollable中的controller就是这个NestedScrollController,所以在updateopsition时会把旧的detach调,把新生成的position attach进来
另外,在dispose中也会detach
由此我们就知道啦,因为开启了缓存后就不会调用划出屏幕的页面的dispose,自然所有子scrollable的position都存在nestedScrollController里面了,当发生滑动时,遍历调用positions数组,就导致屏幕外的列表也跟着滑动了~
既然开启了缓存,手动dispose肯定是没啥意义的,实际上我们只要在页面切换过后把未显示的position 给detach掉就好了。
然鹅,因为flutter不支持反射,子布局传递的position我们拿不到,nestedScrollController我们也不能直接拿到=。=
不过有一个对象我们之前见到过,scrollable就是通过他获取controller的,而position则是传给了获取到的controller 就是PrimaryScrollController了,所以我打算在中间第三者插足,对传递Position的PrimaryScrollController进行Hook
在使用的时候把子列表添加进去,并设置对应的GlobalKey。
然后监听Tab切换
以上是我的方案,有问题的话还希望老哥帮忙指正,也希望有其他思路的老哥指点一下~~
上一下Github项目地址 用Flutter写的WanAndroid 其中用到了这个方案
= =
3
ListView的基础创建使用有三种方式:
通过默认构造函数来创建列表,应用场景 = 短列表
这种方式创建的列表存在一个问题:对于那些长列表或者需要较昂贵渲染开销的子组件,即使还没有出现在屏幕中但仍然会被ListView所创建,这将是一项较大的开销,使用不当可能引起性能问题甚至卡顿。
长列表
列表子项之间需要分割线
ListView的进阶使用主要包括:下拉刷新 上拉加载
在Flutter中,ListView结合RefreshIndicator组件实现下拉刷新
通过包裹一层RefreshIndicator,自定义onRefresh回调方法实现
方式有两种:
通过ListView.controller属性可以判断ListView是否滑动到了底部,再进行上拉加载
NotificationListener是一个Widget,可监听子Widget发出的Notification
ListView在滑动时中会发出ScrollNotification类型的通知,可通过监听该通知得到ListView的滑动状态,判断是否滑动到了底部,从而进行上拉加载
NotificationListener有一个onNotification属性,定义了监听的回调方法,通过它来处理加载更多逻辑
不定期分享关于 安卓开发 的干货,追求 短、平、快 ,但 却不缺深度 。
选择一个aar文件,我这里用DynamsoftBarcodeReader.aar。
把目录flutter/examples/hello_services/android/导入到Android Studio中。
点击File New New Module,选择Import .JAR/.AAR Package,添加AAR文件。打开工程属性,添加依赖模块就可以了。