前言

前一篇已经开发了大部分框架,包含视频上下滑动播放,这次将上次未完成的数据显示友好显示,以及底部音乐走马灯特效,另外优化了加载数据的bug,在dart语言里 & 会自动变成&  另外优化了代码逻辑.

本系列会持续更新,将各个模块及功能持续完善,地址:https://github.com/WangCharlie/douyin  欢迎各位fork 和star. 谢谢!

运行效果如下图:

修复Dart语言 URL显示错误.

经过反复则是,发现url 在tostring()方法执行后 会把原来的 &替换成&amp,  所以暂时只能这样替换了 url = url.replaceAll('&', '&')来修复问题了

  1. getVideos(BillboardData v) async {
  2. try {
  3. var url = v.link.split("/")[5];
  4. var response = await http.get(
  5. api.video + url + "&dytk",
  6. headers: api.headers,
  7. );
  8. VideoData videoData = VideoData.fromJson(jsonDecode(response.body));
  9. //获取无水印的视频地址
  10. api.getRedirects(videoData.itemList[0].video.playaddr.uri).then((url) => {
  11. url = url.replaceAll('&amp', '&'),
  12. if (url != '')
  13. {
  14. videos.add(VideoItem(
  15. data: videoData,
  16. videourl: url,
  17. )),
  18. //print(url),
  19. }
  20. });
  21. } catch (ex) {
  22. print(ex);
  23. }
  24. }

  

对数据友好格式化显示

如下图显示数据通常超过1000 会显示1k,超过10000显示1m,这样更加友好显示数据.  主要使用了package:flutter_money_formatter 这个组件

1,先引用 import 'package:flutter_money_formatter/flutter_money_formatter.dart';

2,使用如下方法

  1. FlutterMoneyFormatter fmf =
  2. FlutterMoneyFormatter(amount: double.parse(widget.favorite.toString()));
  3.  
  4. FlutterMoneyFormatter fmf2 =
  5. FlutterMoneyFormatter(amount: double.parse(widget.comments));

3,显示的方法如下

  1. fmf.output.compactNonSymbol

 

完整的实现代码如下:

  1. return Align(
  2. alignment: Alignment.bottomRight,
  3. widthFactor: 100.0,
  4. child: Column(
  5. mainAxisAlignment: MainAxisAlignment.end,
  6. mainAxisSize: MainAxisSize.min,
  7. children: <Widget>[
  8. _getFollowAction(),
  9. _getSocialAction(
  10. icon: DouyinIcons.heart,
  11. title: '${fmf.output.compactNonSymbol}'),
  12. _getSocialAction(
  13. icon: DouyinIcons.chat_bubble,
  14. title: '${fmf2.output.compactNonSymbol}'),
  15. _getSocialAction(
  16. icon: DouyinIcons.reply, title: '分享', isShare: true),
  17. _getMusicPlayerAction()
  18. ],
  19. ));
  20. }

底部音乐名字走马灯特效

先引入 import 'package:marquee_widget/marquee_widget.dart';

反复测试后发现,这里需要设置width,否则没有效果,切记.  并使用container包含起来

  1. Container(
  2. width: 150,
  3. child: Marquee(
  4. child: Text('${widget.musicName} - ${widget.authorName}'),
  5. direction: Axis.horizontal,
  6. textDirection: TextDirection.ltr,
  7. animationDuration: Duration(seconds: 1),
  8. directionMarguee: DirectionMarguee.oneDirection,
  9. ),
  10. ),
  11. ])

音乐图标旋转效果

这里主要模仿抖音的音乐按钮旋转起来的特效,目前还未实现的地方是哪个音乐字符飞出来消失

改造后的代码如下,先使用  SingleTickerProviderStateMixin,当元素显示时才播放动画效果

  1. class _ActionsToolbarState extends State<ActionsToolbar>
  2. with SingleTickerProviderStateMixin {
  3. static const double ActionWidgetSize = 60.0;
  4. static const double ActionIconSize = 35.0;
  5. static const double ShareActionIconSize = 25.0;
  6. static const double ProfileImageSize = 50.0;
  7. static const double PlusIconSize = 20.0;
  8. AnimationController animationController;

然后设置初始化状态,以及各种初始化参数。间隔 seconds: 5,并且在初始化状态下把animationController 创建出来,下面的方法使用得到

  1. @override
  2. void initState() {
  3. super.initState();
  4. animationController = new AnimationController(
  5. vsync: this,
  6. duration: new Duration(seconds: 5),
  7. );
  8. animationController.repeat();
  9. }

这里是完整的播放图标改造后的代码

  1. Widget _getMusicPlayerAction() {
  2. return Container(
  3. margin: EdgeInsets.only(top: 10.0),
  4. width: ActionWidgetSize,
  5. height: ActionWidgetSize,
  6. child: Column(children: [
  7. Container(
  8. decoration: new BoxDecoration(
  9. borderRadius: BorderRadius.all(Radius.circular(25.0)),
  10. color: Colors.black54,
  11. ),
  12. padding: EdgeInsets.all(11.0),
  13. height: ProfileImageSize,
  14. width: ProfileImageSize,
  15. child: AnimatedBuilder(
  16. animation: animationController,
  17. child: Container(
  18. decoration: BoxDecoration(
  19. shape: BoxShape.circle,
  20. gradient: musicGradient,
  21. //border: Border.all(color: Colors.black87, width: 11.0),
  22. image: DecorationImage(
  23. image: NetworkImage(widget.coverImg),
  24. fit: BoxFit.cover,
  25. ),
  26. ),
  27. ),
  28. builder: (BuildContext context, Widget _widget) {
  29. return Transform.rotate(
  30. angle: animationController.value * 6.3,
  31. child: _widget,
  32. );
  33. },
  34. ),
  35.  
  36. // decoration: BoxDecoration(
  37. // shape: BoxShape.circle,
  38. // gradient: musicGradient,
  39. // border: Border.all(color: Colors.black87, width: 11.0),
  40. // image: DecorationImage(
  41. // image: NetworkImage(widget.coverImg),
  42. // fit: BoxFit.cover,
  43. // ),
  44. // ),
  45. ),
  46. ]));
  47. }

未完成的还有搜索界面,消息页面、关注,登录界面,后续会继续完善这些界面

结语

本博客会持续更新,将在业余时间将其他的功能完善。请持续关注本博客,代码地址:https://github.com/WangCharlie/douyin

欢迎各位点击star 和fork 代码.

第三篇-用Flutter手撸一个抖音国内版,看看有多炫的更多相关文章

  1. 第二篇-用Flutter手撸一个抖音国内版,看看有多炫

    前言 继上一篇使用Flutter开发的抖音国际版 后再次撸一个国内版抖音,大部分功能已完成,主要是Flutter开发APP速度很爽,  先看下图 项目主要结构介绍 这次主要的改动在api.dart 及 ...

  2. 第四篇-用Flutter手撸一个抖音国内版,看看有多炫

    前言 这次对布局进行优化,主要包含了首页tabview pageview 以及添加几个按钮的操作过程.主要使用到stack层叠布局,tabpview和pageview,tabview两个页面,一个关注 ...

  3. 第五篇- 抖音的强大对手来了,用Flutter手撸一个抖音国际版,看看有多炫

    前言 由于中间几个月项目天天加班,导致没没时间更新,最近一段时间对前端进行了重构,加了很多页面,如登录.注册.关注.个人中心等,目前写这个纯属业余个人爱好,所以断断续续的继续在做...... 前端地址 ...

  4. Golang:手撸一个支持六种级别的日志库

    Golang标准日志库提供的日志输出方法有Print.Fatal.Panic等,没有常见的Debug.Info.Error等日志级别,用起来不太顺手.这篇文章就来手撸一个自己的日志库,可以记录不同级别 ...

  5. 使用Flutter开发的抖音国际版

    简介 最近花了两天时间研究使用Flutter开发一个抖音国际版. 先上图,个人感觉使用Flutter开发app快得不要不要的额.  两天就基本可以开发个大概出来.   最主要是热更新,太方便实时调整U ...

  6. 使用Java Socket手撸一个http服务器

    原文连接:使用Java Socket手撸一个http服务器 作为一个java后端,提供http服务可以说是基本技能之一了,但是你真的了解http协议么?你知道知道如何手撸一个http服务器么?tomc ...

  7. 【手撸一个ORM】MyOrm的使用说明

    [手撸一个ORM]第一步.约定和实体描述 [手撸一个ORM]第二步.封装实体描述和实体属性描述 [手撸一个ORM]第三步.SQL语句构造器和SqlParameter封装 [手撸一个ORM]第四步.Ex ...

  8. C#基于Mongo的官方驱动手撸一个Super简易版MongoDB-ORM框架

    C#基于Mongo的官方驱动手撸一个简易版MongoDB-ORM框架 如题,在GitHub上找了一圈想找一个MongoDB的的ORM框架,未偿所愿,就去翻了翻官网(https://docs.mongo ...

  9. 通过 Netty、ZooKeeper 手撸一个 RPC 服务

    说明 项目链接 微服务框架都包括什么? 如何实现 RPC 远程调用? 开源 RPC 框架 限定语言 跨语言 RPC 框架 本地 Docker 搭建 ZooKeeper 下载镜像 启动容器 查看容器日志 ...

随机推荐

  1. csp-j2019游记

    我一pj蒟蒻这点水平还来写游记? 算了,毕竟是第一次,记录一下吧 noip->csp 话说我跟竞赛是不是天生八字不合啊...... 小学的时候学小奥,等我开始报名比赛,当时似乎所有竞赛都被叫停了 ...

  2. Jmeter 性能测试(需求/指标分析与定义)

    1.一般而言,被测对象的性能需求,会在用户需求规格说明书中给出,如单位时间内的访问量需达到多少?业务响应时间不超过多少?业务成功率不低于多少?硬件资源耗用要在一个合理的范围中. 如下性能指标非常明确 ...

  3. 【原创】Linux Mutex机制分析

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  4. N - 寿司晚宴 HYSBZ - 4197 状压dp

    N - 寿司晚宴 HYSBZ - 4197 推荐题解 这个题目我觉得还是很难的,借助题解写出来的,题解还看了很久,现在还是不是很理解. 首先这个数比较大有500,如果直接就像这个题目S - Query ...

  5. SpringBoot:Demo

    目录 Demo 准备工作 登录+拦截器 Restful CRUD Restful架构 查询所有员工 添加员工 员工修改功能 HiddenHttpMethodFilter 删除员工 定制错误页面 注销功 ...

  6. TD-LTE华为 DBS3900数据配置实践 典型案例

    案例:华为 DBS3900 双基站二扇区配置(同频切换) 一.数据配置前的硬件准备: HW-DBS3900: (1#基站名称) FAN (风扇),安装在 16#槽位: LBBP (基带处理单板),安装 ...

  7. 高性能mysql第三版读书笔记3

    innodb以前不支持高并发,在搞病房下就是悲剧,全部卡在mutex(缓冲池mutex)上,现在通过线程调度器控制线程怎么进入内核访问数据,参数为innodb_thread_concurrency,它 ...

  8. @Resource、@Autowired等几个注解的区别

    1.@Resource注解和@Autowired的区别 @Autowired注解:是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false ...

  9. 今天,你遇到redis线上连接超时了吗?

    一封报警邮件,大量服务节点 redis 响应超时. 又来,好烦. redis 响应变慢,查看日志,发现大量 TimeoutException. 大量TimeoutException,说明当前redis ...

  10. call(),apply(),bind() 区别和用法

    call call 方法第一个参数是要绑定给this的值,后面传入的是一个参数列表.当第一个参数为null.undefined的时候,默认指向window. var arr = [1, 2, 3, 8 ...