sqflite适用于需要排序,筛查数据的需求,是一个完整的数据库。
创新互联是一家专业的网站制作公司,提供的服务包括:成都品牌网站建设,网站设计,网页设计,我们是一家专业网络公司,做网站,我们是认真的。我们是成都网站制作,成都网站建设的先行者,一切以客户的利益为设计方向,能够为不同行业的客户提供全面、长期、深入的网络解决方案。 创新互联根据客户的具体需求,提供从策划、创意、制作、执行等服务。
SP就是一个简单的缓存,都是存在一个文档里的,无法排序查询和单独更新数组的单个对象。
不过Flutter的SP并不好用,缓存的需求建议你使用local_cache_sync这个库,比较易于使用。
此控件的package我已经托管到了 pub仓库
如果你被墙住了,也可以看 国内镜像
使用方式就是在你的flutter pubspec.yaml中添加依赖:
然后flutter packages get更新依赖即可
最近写demo时发现Flutter自带的ListView widget很简陋,没有分隔线,没有section/row之分,也没有sectionHeader,如果要实现一个有分割线,有section区分,有section header的ListView,耦合会非常严重:
在 上没有找到封装好的这种TableView,于是乎决定自己写一个,命名为SectionTableView
本人是iOS开发,所以习惯了iOS上的UITableView的调用风格,所以在实现flutter的SectionTableView时,决定实现如下功能
为了实现这些功能,并且方便后期增加滚动功能,上下拉刷新功能,使用了StatefulWidget作为父类:
接着在对应的_SectionTableViewState中的build方法中,返回ListView:
熟悉flutter ListView的同学知道,ListView的builder类方法,有一个itemBuilder回调函数,参数是当前的上下文,和将要渲染的行索引index,index对应想要获取的某一行控件(cell或者叫ListItem),返回非空的组件就证明这个index有值,返回null就表示列表到尽头了。
我们需要做的就是对index进行映射,判断当前index对应的控件,应该是列表里的section header,还是分隔线devider,还是某一行的真正内容cell。
出于性能的考虑,不可能每次调用 _buildCell的时候,都计算一遍index对应的section和row的位置,所以定义了一个类成员变量indexPathSearch,是数组,数组长度就是ListView所有的行,当 _buildCell 的参数index大于等于indexPathSearch的长度的时候,就返回null,表示列表内容到此为止了。
indexPathSearch里每一个元素,就是index对应的section和row(称为indexPath),index指向实际行(cell)的时候,section和row都是大于等于0的,当section大于等于0,row==-1的时候,表示这里是一个section header,当两者都等于-1的时候,表示这里是一个分割线:
计算好了index到indexPath的映射,剩下的就好说了,在_buildCell中,提取indexPath并判断indexPath的内容,返回对应的控件:
这是我的第一个flutter package,目前还很简陋,flutter目前尚且如此,所以大家一起改善它,
下一步将优化如下内容:
如果大家喜欢,请多多star我的 项目GitHub
于是就有了写作本文的动力,--------解决同时连接多台蓝牙设备!!!
flutter_blue 适合于单台的蓝牙设备,使用起来简单
flutter_reactive_ble 适合于单台的蓝牙设备,多台蓝牙设备也可以用
flutter_ble_lib 适合于单台的蓝牙设备,多台蓝牙设备也可以用,可以在模拟器上进行调试蓝牙
感觉后2个第三方库都可以使用,本人先入为主使用了flutter_reactive_ble,所以本文以flutter_reactive_ble为基础进行介绍
先声明4个全局变量,后面会用到
开始扫描
如果扫描过程,不使用过滤条件,withServices这个参数可以给个空数组
停止扫描如下
连接设备
断开设备,
每连接成功一个设备后,就会产生一个_connectionStreamSubscription,对应设备的断开,就用对应的StreamSubscription去断开, 可以用一个HashMap,去记录 连接成功的设备 与 StreamSubscription 的对应关系
去扫描服务,并过滤服务,扫描结果服务里面是包含有特征的数组,如: serviceId:[fff0,fff1,fff2,fff3,...]
去监听上报来的数据,参数来自前面扫描到的结果serviceId--服务ID, characteristicId--特征ID,deviceId--设备ID
后面就是各位看官根据自己的需求去做逻辑处理啦。
对设备设置命令,发送请求(写操作),list为整形数据,要写的数据
读取设备的信息(读操作)
flutter 多台蓝牙设备同时连接的分享就到这里喽,小伴们,觉得有点用的话,或者已经看到这里面来的请点个赞吧~~ 后续分享更多有关flutter的文章。如果有疑问的话,请在下方留言~
过一段时间后,我在项目把这个蓝牙库用起来了,基本能满足日常需求.效果如下:
整形数组Listint转为字符串
字符串转整形数组Listint
字符 -------ASCII值
A --------65
B --------66
C --------67
D --------68
基本和AppBar一样,只是他只能在CustomScrollView中使用,应该很常见,滑动的时候固定appbar,就需要用到他.
大部分和appbar一样,主要说下重要的几个:
是否将导航栏部分固定在appbar的位置.这个需求在实际中很常用. 看看效果图.
当 pinned = false:
可以看到appbar并没有固定在最上面,而是根据内容划出了界面.
当 pinned = true :
这个应该是需求中经常用到的效果了.
当floating = false :
当floating = true:
仔细看 ,区别是在列表整体向下滑动时,appbar开始显示的位置不同.
当为false时 ,向下滑动时,会先降列表内容滑动顶部,然后appbar会跟着列表滑动显示出来.如上图
当为true时, 向下滑动时,appbar会先跟着列表滑动显示出来. 然后继续列表的滑动. 如上图
不能单独使用要配合 ****floating 和 ****pinned
具体效果看官网地址
是否展开,默认false,直接看值为true的效果图,就明白了.
可以再里面添加扩展的内容:
通过测试发现 **后面不是 FlexibleSpaceBar 的话, stretch = true 无效. **
和Padding一样.子控件是 sliver 类型...
上图中在padding中添加了一个背景色为青色的容器widget
里面可以设置不是 sliver 类型的widget。如上图中的 padding中添加的 container
就两个协议,一个是布局协议一个展示协议.基本和GridView一样.也有count和extext... 不设置个数默认无数个
SliverChildListDelegate 这种方式前提是知道cell个数,比较少,好搭建
SliverChildBuilderDelegate 这种方式,可以根据数组去创建,不知道cell个数
和listview差不多.也是协议 不设置个数默认无数个
讲道理我起的好长的名字啊,不过文如上题,搜索到这里的兄弟应该都知道我说的是啥情况,正好
~~
我这个方案可能有点笨拙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