Flutter自适应瀑布流


1.图片自适应

2.自适应标签

3.上拉刷新和下拉加载

4.底部的点赞按钮可以去掉或者自己修改样式,我这里使用的like_button库

注:本文使用的库:为啥这么多呢,因为我把图片缓存这样东西都加上了,单纯的瀑布流就用waterfall_flow

waterfall_flow: ^3.0.1

extended_image: any

extended_sliver: any

ff_annotation_route_library: any

http_client_helper: any

intl: any

like_button: any

loading_more_list: any

pull_to_refresh_notification: any

url_launcher: any

1.图片自适应:

Widget image = Stack(

children: [

ExtendedImage.network(

item.imageUrl,

shape: BoxShape.rectangle,

//clearMemoryCacheWhenDispose: true,

border: Border.all(color: Colors.grey.withOpacity(0.4), width: 1.0),

borderRadius: const BorderRadius.all(

Radius.circular(10.0),

),

loadStateChanged: (ExtendedImageState value) {

if (value.extendedImageLoadState == LoadState.loading) {

Widget loadingWidget = Container(

alignment: Alignment.center,

color: Colors.grey.withOpacity(0.8),

child: CircularProgressIndicator(

strokeWidth: 2.0,

valueColor:

AlwaysStoppedAnimation(Theme.of©.primaryColor),

),

);

if (!konwSized) {

//todo: not work in web

loadingWidget = AspectRatio(

aspectRatio: 1.0,

child: loadingWidget,

);

}

return loadingWidget;

} else if (value.extendedImageLoadState == LoadState.completed) {

item.imageRawSize = Size(

value.extendedImageInfo.image.width.toDouble(),

value.extendedImageInfo.image.height.toDouble());

}

return null;

},

),

Positioned(

top: 5.0,

right: 5.0,

child: Container(

padding: const EdgeInsets.all(3.0),

decoration: BoxDecoration(

color: Colors.grey.withOpacity(0.6),

border: Border.all(color: Colors.grey.withOpacity(0.4), width: 1.0),

borderRadius: const BorderRadius.all(

Radius.circular(5.0),

),

),

child: Text(

‘${index + 1}’,

textAlign: TextAlign.center,

style: const TextStyle(fontSize: fontSize, color: Colors.white),

),

),

)

],

);

if (konwSized) {

image = AspectRatio(

aspectRatio: item.imageSize.width / item.imageSize.height,

child: image,

);

} else if (item.imageRawSize != null) {

image = AspectRatio(

aspectRatio: item.imageRawSize.width / item.imageRawSize.height,

child: image,

);

}

return Column(

crossAxisAlignment: CrossAxisAlignment.start,

children: [

image,

const SizedBox(

height: 5.0,

),

buildTagsWidget(item),

const SizedBox(

height: 5.0,

),

buildBottomWidget(item),

],

);

}

2.自适应标签:

Widget buildTagsWidget(

TuChongItem item, {

int maxNum = 6,

}) {

const double fontSize = 12.0;

return Wrap(

runSpacing: 5.0,

spacing: 5.0,

children: item.tags.take(maxNum).map((String tag) {

final Color color = item.tagColors[item.tags.indexOf(tag)];

return Container(

padding: const EdgeInsets.all(3.0),

decoration: BoxDecoration(

color: color,

border: Border.all(color: Colors.grey.withOpacity(0.4), width: 1.0),

borderRadius: const BorderRadius.all(

Radius.circular(5.0),

),

),

child: Text(

tag,

textAlign: TextAlign.start,

style: TextStyle(

fontSize: fontSize,

color: color.computeLuminance() < 0.5

? Colors.white
Colors.black),

),

);

}).toList());

}

3.上拉刷新和下拉加载

class PullToRefreshHeader extends StatelessWidget {

const PullToRefreshHeader(this.info, this.lastRefreshTime, {this.color});

final PullToRefreshScrollNotificationInfo info;

final DateTime lastRefreshTime;

final Color color;

@override

Widget build(BuildContext context) {

if (info == null) {

return Container();

}

String text = ‘’;

if (info.mode == RefreshIndicatorMode.armed) {

text = ‘Release to refresh’;

} else if (info.mode == RefreshIndicatorMode.refresh ||

info.mode == RefreshIndicatorMode.snap) {

text = ‘Loading…’;

} else if (info.mode == RefreshIndicatorMode.done) {

text = ‘Refresh completed.’;

} else if (info.mode == RefreshIndicatorMode.drag) {

text = ‘Pull to refresh’;

} else if (info.mode == RefreshIndicatorMode.canceled) {

text = ‘Cancel refresh’;

}

final TextStyle ts = const TextStyle(

color: Colors.grey,

).copyWith(fontSize: 13);

final double dragOffset = info?.dragOffset ?? 0.0;

final DateTime time = lastRefreshTime ?? DateTime.now();

final double top = -hideHeight + dragOffset;

return Container(

height: dragOffset,

color: color ?? Colors.transparent,

//padding: EdgeInsets.only(top: dragOffset / 3),

//padding: EdgeInsets.only(bottom: 5.0),

child: Stack(

children: [

Positioned(

left: 0.0,

right: 0.0,

top: top,

child: Row(

mainAxisAlignment: MainAxisAlignment.center,

crossAxisAlignment: CrossAxisAlignment.center,

children: [

Expanded(

child: Container(

alignment: Alignment.centerRight,

child: RefreshImage(top),

margin: const EdgeInsets.only(right: 12.0),

),

),

Column(

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

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

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

img

img

img

img

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

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

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

如何做好面试突击,规划学习方向?

面试题集可以帮助你查漏补缺,有方向有针对性的学习,为之后进大厂做准备。但是如果你仅仅是看一遍,而不去学习和深究。那么这份面试题对你的帮助会很有限。最终还是要靠资深技术水平说话。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。建议先制定学习计划,根据学习计划把知识点关联起来,形成一个系统化的知识体系。

学习方向很容易规划,但是如果只通过碎片化的学习,对自己的提升是很慢的。

同时我还搜集整理2020年字节跳动,以及腾讯,阿里,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节

image

在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多。

image

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

的学习,对自己的提升是很慢的。

同时我还搜集整理2020年字节跳动,以及腾讯,阿里,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节

[外链图片转存中…(img-dHg589jI-1712272082495)]

在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多。

[外链图片转存中…(img-1tScUwcD-1712272082495)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值