Flutter动手实战,大佬手把手教你如何仿写出大厂的APP,推荐

整个项目就是以上这些文件了 (具体的就不一个一个分析了,如,感兴趣,大家可以 clone 源码运行起来,自然就清除了)

项目功能详细概述(所用知识点)

首先,来看看首页功能及所用知识点,首页重点看下以下功能实现:

  • 渐隐渐现的 appBbar
  • 搜索组件的封装
  • 语音搜索页面
  • banner组件
  • 浮动的 icon 导航
  • 渐变不规则带有背景图的网格导航

渐隐渐现的 appBbar

先来看看具体效果,一睹芳容,如图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

滚动的时候 appBar 背景色从透明变成白色或白色变成透明,这里主要用了 flutterNotificationListener 组件,它会去监听组件树冒泡事件,当被它包裹的的组件*(子组件)* 发生变化时,Notification 回调函数会被触发,所以,通过它可以去监听页面的滚动,来动态改变 appBar 的透明度*(alpha)*,代码如下:

NotificationListener(
onNotification: (scrollNotification) {
if (scrollNotification is ScrollUpdateNotification &&
scrollNotification.depth == 0) {
_onScroll(scrollNotification.metrics.pixels);
}
return true;
},
child: …

Tips:
scrollNotification.depth 的值 0 表示其子组件*(只监听子组件,不监听孙组件)*;
scrollNotification is ScrollUpdateNotification 来判断组件是否已更新,ScrollUpdateNotification 是 notifications 的生命周期一种情况,分别有一下几种:

  • ScrollStartNotification 组件开始滚动
  • ScrollUpdateNotification 组件位置已经发生改变
  • ScrollEndNotification 组件停止滚动
  • UserScrollNotification 不清楚

这里,我们不探究太深入,如想了解可多查看源码。

_onScroll 方法代码如下:

void _onScroll(offset) {
double alpha = offset / APPBAR_SCROLL_OFFSET; // APPBAR_SCROLL_OFFSET 常量,值:100;offset 滚动的距离

//把 alpha 值控制值 0-1 之间
if (alpha < 0) {
alpha = 0;
} else if (alpha > 1) {
alpha = 1;
}
setState(() {
appBarAlpha = alpha;
});
print(alpha);
}

搜索组件的封装

搜索组件效果如图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以下是首页调用 searchBar 的代码:

SearchBar(
searchBarType: appBarAlpha > 0.2 //searchBar 的类:暗色、亮色
? SearchBarType.homeLight
: SearchBarType.home,
inputBoxClick: _jumpToSearch, //点击回调函数
defaultText: SEARCH_BAR_DEFAULT_TEXT, // 提示文字
leftButtonClick: () {}, //左边边按钮点击回调函数
speakClick: _jumpToSpeak, //点击话筒回调函数
rightButtonClick: _jumpToUser, //右边边按钮点击回调函数
),

其实就是用 TextField 组件,再加一些样式,需要注意点是:onChanged,他是 TextField 用来监听文本框是否变化,通过它我们来监听用户输入,来请求接口数据;
具体的实现细节,请查阅源码: 点击查看searchBar源码

语音搜索页面

语音搜索页面效果如图:由于模拟器无法录音,所以无法展示正常流程,如果录音识别成功后会返回搜索页面,在项目预览视频中可以看到正常流程。

[图片上传失败…(image-190ee2-1589860267422)]

语音搜索功能使用的是百度的语言识别SDK,原生接入之后,通过 MethodChannel 和原生Native端通信,这里不做重点讲述(这里会涉及原生Native的知识)。

重点看看点击录音按钮时的动画实现,这个动画用了 AnimatedWidget 实现的,代码如下:

class AnimatedWear extends AnimatedWidget {
final bool isStart;
static final _opacityTween = Tween(begin: 0.5, end: 0); // 设置透明度变化值
static final _sizeTween = Tween(begin: 90, end: 260); // 设置圆形线的扩散值

AnimatedWear({Key key, this.isStart, Animation animation})
super(key: key, listenable: animation);

@override
Widget build(BuildContext context) {
final Animation animation = listenable; // listenable 继承 AnimatedWidget,其实就是控制器,会自动监听组件的变化
return Container(
height: 90,
width: 90,
child: Stack(
overflow: Overflow.visible,
alignment: Alignment.center,
children: [

// 扩散的圆线,其实就是用一个圆实现的,设置圆为透明,设置border
Positioned(
left: -((_sizeTween.evaluate(animation) - 90) / 2), // 根据 _sizeTween 动态设置left偏移值
top: -((_sizeTween.evaluate(animation) - 90) / 2), // 根据 _sizeTween 动态设置top偏移值
child: Opacity(
opacity: _opacityTween.evaluate(animation), // 根据 _opacityTween 动态设置透明值
child: Container(
width: isStart ? _sizeTween.evaluate(animation) : 0, // 设置 宽
height: _sizeTween.evaluate(animation), // 设置 高
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(
_sizeTween.evaluate(animation) / 2),
border: Border.all(
color: Color(0xa8000000),
)),
),
),
),
],
),
);
}
}

其他细节,如:点击时提示录音,录音失败提示,点击录音按钮出现半透明黑色圆边框,停止后消失等,请查看源码

banner组件

效果如图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

banner使用的是flutter的 flutter_swiper 插件实现的,代码如下:

Swiper(
itemCount: bannerList.length, // 滚动图片的数量
autoplay: true, // 自动播放
pagination: SwiperPagination( // 指示器
builder: SquareSwiperPagination(
size: 6, // 指示器的大小
activeSize: 6, // 激活状态指示器的大小
color: Colors.white.withAlpha(80), // 颜色
activeColor: Colors.white, // 激活状态的颜色
),
alignment: Alignment.bottomRight, // 对齐方式
margin: EdgeInsets.fromLTRB(0, 0, 14, 28), // 边距
),
itemBuilder: (BuildContext context, int index) { // 构造器
return GestureDetector(
onTap: () {
CommonModel model = bannerList[index];
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WebView(
url: model.url,
),
),
);
},
child: Image.network(
bannerList[index].icon,
fit: BoxFit.fill,
),
);
},
),

具体使用方法,可以去 flutter的官方插件库 pub.dev 查看:点击flutter_swiper查看

Tips:
需要注意的是,我稍改造了一下指示器的样式,flutter_swiper 只提供了 3 种指示器样式,如下:

  • dots = const DotSwiperPaginationBuilder(),圆形
  • fraction = const FractionPaginationBuilder(),百分数类型的,如:1/6,表示6页的第一页
  • rect = const RectSwiperPaginationBuilder(),矩形

并没有上图的激活状态的长椭圆形,其实就是按葫芦画瓢,自己实现一个长椭圆类型,如知详情,可点击查看长椭圆形指示器源码

浮动的 icon 导航

icon导航效果如图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

icon导航浮动在banner之上,其实用的是 flutterStack 组件,Stack 组件能让其子组件堆叠显示,它通常和 Positioned 组件配合使用,布局结构代码如下:

ListView(
children: [
Container(
child: Stack(
children: [
Container( … ), //这里放的是banner的代码
Positioned( … ), //这个就是icon导航,通过 Positioned 固定显示位置
],
),
),
Container( … ), // 这里放的网格导航及其他
],
),

渐变不规则带有背景图的网格导航

网格导航效果如图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如图,网格导航分为三行四栏,而第一行分为三栏,每一行的第一栏宽度大于其余三栏,其余三栏均等,每一行都有渐变色,而且第一、二栏都有背景图;
flutterColumn 组件能让子组件竖轴排列, Row 组件能让子组件横轴排列,布局代码如下:

Column( // 最外面放在 Column 组件
children: [
Container( // 第一行包裹 Container 设置其渐变色
height: 72,
decoration: BoxDecoration(
gradient: LinearGradient(colors: [ //设置渐变色
Color(0xfffa5956),
Color(0xffef9c76).withAlpha(45)
]),
),
child: Row( … ), // 第一行
),
Padding(
padding: EdgeInsets.only(top: 1), // 设置行直接的间隔
),
Container(
height: 72,
decoration: BoxDecoration(
gradient: LinearGradient(colors: [ //设置渐变色
Color(0xff4b8fed),
Color(0xff53bced),
]),
),
child: Row( … ), // 第二行
),
Padding(
padding: EdgeInsets.only(top: 1), // 设置行直接的间隔
),
Container(
height: 72,
decoration: BoxDecoration(
gradient: LinearGradient(colors: [ //设置渐变色
Color(0xff34c2aa),
Color(0xff6cd557),
]),
),
child: Row( … ), // 第三行
),
],
),

其实,具体实现的细节还是很多的,比如:

  • 怎么设置第一栏宽度偏大,其他均等;
  • 第一行最后一栏宽度是其他的2倍;
  • 第一、二栏的别截图及浮动的红色气泡tip等;

在这里就不细讲,否则篇幅太长,如想了解详情 点击查看源码

其次,再来看看目的地页面功能及所用知识点,重点看下以下功能实现:

  • 左右布局tabBarListView
  • 目的地搜索页面

左右布局tabBarListView

具体效果如图:点击左边标签可以切换页面,左右滑动也可切换页面,点击展开显示更多等

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其实官方已经提供了 tabBarTabBarView 组件可以实现上下布局的效果*(旅拍页面就是用这个实现的)*,但是它无法实现左右布局,而且不太灵活,所以,我使用的是 vertical_tabs插件, 代码如下:

VerticalTabView(
tabsWidth: 88,
tabsElevation: 0,
indicatorWidth: 0,
selectedTabBackgroundColor: Colors.white,
backgroundColor: Colors.white,
tabTextStyle: TextStyle(
height: 60,
color: Color(0xff333333),
),
tabs: tabs,
contents: tabPages,
),
),

具体使用方法,在这里就不赘述了,点击vertical_tabs查看

Tips:
这里需要注意的是:展开显示更多span标签组件的实现,因为,这个组件在很多的其他组件里用到而且要根据接口数据动态渲染,且组件自身存在状态的变化,这种情况下,最好是把他单独封装成一个组件*(widget)*,否则,很难控制自身状态的变化,出现点击没有效果,或点击影响其他组件。

目的地搜索页面

效果如图:点击搜索结果,如:点击‘一日游‘,会搜索到‘一日游‘的相关数据

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

目的地搜索页面,大多都是和布局和对接接口的代码,在这里就不再赘述。

然后就是旅拍页面功能及所用知识点,重点看下以下功能实现:

  • 左右布局tabBarListView

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

学习分享

在当下这个信息共享的时代,很多资源都可以在网络上找到,只取决于你愿不愿意找或是找的方法对不对了

很多朋友不是没有资料,大多都是有几十上百个G,但是杂乱无章,不知道怎么看从哪看起,甚至是看后就忘

如果大家觉得自己在网上找的资料非常杂乱、不成体系的话,我也分享一套给大家,比较系统,我平常自己也会经常研读。

2021最新上万页的大厂面试真题

七大模块学习资料:如NDK模块开发、Android框架体系架构…

只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。

这份体系学习笔记,适应人群:
第一,学习知识比较碎片化,没有合理的学习路线与进阶方向。
第二,开发几年,不知道如何进阶更进一步,比较迷茫。
第三,到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。如果你有需要,我这里恰好有为什么,不来领取!说不定能改变你现在的状态呢!
由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示 。

经常研读。

2021最新上万页的大厂面试真题

[外链图片转存中…(img-X5IvhzRI-1711747637289)]

七大模块学习资料:如NDK模块开发、Android框架体系架构…

[外链图片转存中…(img-bkOQiLvJ-1711747637290)]

只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。

这份体系学习笔记,适应人群:
第一,学习知识比较碎片化,没有合理的学习路线与进阶方向。
第二,开发几年,不知道如何进阶更进一步,比较迷茫。
第三,到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。如果你有需要,我这里恰好有为什么,不来领取!说不定能改变你现在的状态呢!
由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示 。

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

  • 22
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值