8天让iOS开发者上手Flutter之七

1,126 阅读7分钟

上一篇文章我们已经完成首页聊天页面的导航条和列表展示,今天的任务是完成搜索cell的展示和点击之后的搜索页面的功能。

自定义SearchCell

新建search_cell.dart文件

image.png

实现SearchCell代码

SearchCell的话,因为仅仅只是展示,点击之后就进入搜索页了,应该来说是不需要状态的,所以用一个StatelessWidget就够了。然后布局的方式使用一个Container包含一个Row,Row里面包一个图片和文本就可以了。布局的方式其实多种多样,能实现就好了。完整代码如下: image.png 一个有意思的地方是,flutter里面的Image居然可以设置颜色,而且颜色是设置给图片的。比如我的放大镜图片原本是黑色的,设置红色之后,居然真的变红色了!!!

使用SearchCell

SearchCell的展示就算写完了,然后在ChatPage.dart中使用,我们把ListView的itemBuilder方法抽取出来,然后因为我们多加了一个SearchCell,所以itemCount需要加1,然后取_chatList数据的时候也要处理一下下标。 image.png

自定义SearchPage

新建search_page.dart文件

image.png

简单实现SearchPage

SearchPage作为一个页面,使用StatelessWidget肯定是无法胜任的,所以使用一个StatefulWidget。而由于AppBar的样式和我们需要显示的效果图还是有差别的,所以这里我们不使用Scaffold提供的AppBar了。我们自定义一个SearchBar,配合一个ListView来搭建基本的布局。这里面基本没有新鲜的东西,就简单贴一下代码: image.png SearchBar由于是在SearchPage中使用的,所以就直接定义在SearchPage中了,代码也是先简单定义如下: image.png

点击跳转到SearchPage

image.png 在搜索cell里面实现点击方法,然后跳转到SearchPage,显示效果如图:

实现SearchBar

SearchBar的布局

SearchBar的布局,最外层分为上下两个部分,上面的部分是系统状态栏的高度。下面的部分就是显示搜索条的高度。而搜索条的布局,使用Row分隔为左右两个部分,左侧包含放大镜,文本输入框和删除图片。右侧就是一个返回上级页面的取消。这里主要提一下flutter中的文本框,跟iOS中UITextField真的很不一样,UITextField中左侧的图标,右侧的删除,都是封装在内部的。而在flutter中,文本框TextField真的就只有文本框,没有其他的东西,都需要自己添加。完整代码如下: Snip20210818_60.png

SearchBar事件处理

取消的处理

点击取消需要pop到上一个界面,给取消加一个GestureDetector实现onTap就好了。代码如下: Snip20210818_61.png

清除按钮功能实现

未输入文本的时候,不显示清除按钮。有输入文本的时候,显示清除按钮。点击清除按钮,清空文本内容并隐藏清除按钮。

使用一个bool值_showClear控制清除按钮的显示隐藏。代码如下: image.png

在文本变化的时候,修改_showClear值并刷新状态。文本的变化在TextField的onChanged属性就可以监听到。代码如下: image.png

最后就是清除按钮的点击功能,由于需要清空TextField的文本内容,需要使用到TextEditingController,给TextField的controller属性赋值,然后通过TextEditingController对象清除文本内容。文本清除之后并不会自动调用系统的onChanged方法,自己手动调用一下就好了。代码如下: image.png

SearchBar回调文本框的内容

文本框的内容变化的时候,需要回调给SearchBar外部,这样我们才能在SearchPage页面进行搜索内容。使用一个回调作为参数就可以实现了。代码如下: image.png onChanged是一个闭包属性,在初始化SearchBar的时候传入,在TextField的文本变化的时候调用闭包,并将文本作为参数回传给SearchBar外部。因为将onChanged作为了必传参数,所以编译器自然会在用到了SearchBar的地方报错。很容易找到报错的地方,加个参数就好了。 image.png SearchBar相关的代码就算差不多完成了,其实可以将SearchBar单独作为一个文件独立出来。接下来就是处理SearchPage了

实现SearchPage

搜索页面的搜索功能,往细了说,可以搜索很多内容,我们这里只是简单的搜索名字,只要名字包含输入的内容,就将搜索结果展示出来。由于这里对中文名进行搜索的时候,能匹配到的数据比较少,所以这里已经将网络请求返回的名字由中文改为英文名字了。前面展示中文名字的截图就不做修改了。

SearchPage的搜索功能

添加datas数据源

要实现SearchPage的搜索功能,那么它首先必须要有数据源,很明显它的数据源是从首页来的。先定义一个datas,作为必传参数,然后通过外部层层传递过来。 image.png datas定义好了以后,报红色错误的地方,就是需要传参数的地方,很方便,都不用我们自己去翻哪里需要加参数了。发现SearchCell里面需要传入数据源,同样的方式,在SearchCell里面定义datas,然后在报错的地方处理。 image.png 就这样子顺藤摸瓜,直到来到chat_page将数据源传入就完成了 image.png

SearchPage自己的数据源

SearchPage需要展示搜索之后的结果,所以自己定义一个数组用来存放搜索的结果。并且暂时先使用Text做一个最简单的展示。代码如下: image.png

实现搜索功能并展示数据

搜索的功能实现很简单,就是判断数据源里面的名字是否包含输入的文本,如果包含就全部添加并展示。 代码如下: image.png APP上如图,我输入son,显示结果:

SearchPage的搜索结果列表展示

SearchPage的搜索结果列表展示的数据样式,应该和首页是类似的。所以可以直接使用首页的布局。代码如下: image.png

SearchPage高亮显示搜到的结果

这里的思路是,高亮显示搜到的结果,那么普通的文本肯定是不行了,必须是富文本。如何找到搜索的关键字在文本中的位置呢,这个不用我们考虑了。flutter中对字符串有一个分隔方法split,这个方法跟iOS中的字符串的componentsSeparatedByString:方法类似,根据传入的参数来分隔字符串。这里贴一下iOS的代码: image.png (还是Xcode看着顺眼啊)我们将字符串abcaa以字符a分组,再将分组的结果拼接回原来的字符串。为什么要这么操作?因为重新拼接新字符串的时候,我们就可以处理富文本字符串了。现在回到flutter中来,flutter中拼接的富文本的方式太方便了,RichText花样拼接TextSpan这个我们在前面也讲过了。 image.png _searchKey就是我们输入的文本,在SearchPage中声明属性,在SearchBar的回调中赋值就好了。 image.png image.png 现在测试一下,输入son,APP显示如图:

滚动列表叫回键盘

ListView的滚动,我们在前面已经说过一次,需要将ListView包在NotificationListener里面。然后叫回键盘的代码FocusScope.of(context).requestFocus(FocusNode());这个记住就好了,代码如下: image.png

总结

到这里我们的flutter仿微信Demo功能就差不多完了,还剩最后一篇就是介绍flutter和原生混合开发的一些东西。这个也是实际项目中应该经常会遇到的情况。其实写到这里会发现很多东西和原生都是相通的或者类似的。除了新的语言Dart不是很熟悉之外,其他很多地方比如很多属性的名字,颜色,闭包,都能够看到原生的影子。flutter创造者们也不会闭门造车,都会去借鉴原生里面的东西。