前言

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

前端地址:https://www.pgyer.com/dtok

后端服务器地址:http://47.95.209.198:8181/

注释:由于本人的apple id无法打包ios、所以暂时只打包的android版本,ios版本正在解决账号问题

效果如下:

架构更新

之前技术采用flutter做的前端,后端api则对接的是抖音官方api,由于抖音的官方api更新频繁,导致经常播放不了,所以索性自己来写服务器后端api,那么后端api采用了那些技术咧

  • springcloud 主要是后台控制面板 演示地址:http://47.95.209.198:8181/login
  • elasticsearch 主要对视频数据离线查询
  • ipfs 用于分布式节点存储短视频
  • ethereum 用户激励用户存储短视频、毕竟买服务器存花费够大的

界面更新

  • 支持国家化,多语言切换
  • ipfs上传、下载文件
  • 登录页面
  • 注册页面
  • 上下轮播时优化播放效果
  • 点赞功能

其他功能还在继续完善,各位喜欢的话欢迎点个star 前端项目地址:https://github.com/telsacoin/telsavideo

后端需要的话请留下邮箱

本期最大的优化就是国际化,flutter国家化按以下步骤

在pubspec.yaml文件加上

  flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: ^0.17.0 # Add this line
ffi: ^1.1.2

在底部的flutter设置里添加

# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
generate: true # Add this line

新建多语言包

在lib目录新建子目录l10n

里面添加app_zh.arb文件

内容如下:

{
"home_top_foryou":"推荐",
"home_top_following":"关注",
"home_share":"分享",
"home_buttom_title":"首页",
"home_buttom_discover":"发现",
"home_buttom_notification":"通知",
"home_buttom_persion":"我"
}

在main文件引用

import 'package:flutter_gen/gen_l10n/app_localizations.dart';

在build里加入多语言检测及支持的代码

return MaterialApp(
debugShowCheckedModeBanner: false,
onGenerateTitle: (context) =>
AppLocalizations.of(context)!.home_buttom_title,
home: SplashScreen(),
localeResolutionCallback: (
Locale? locale,
Iterable<Locale> supportedLocales,
) {
return locale;
},
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
theme: ThemeData(
textSelectionTheme: TextSelectionThemeData(
cursorColor: Colors.white,
),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
primarySwatch: Colors.red,
primaryColor: Colors.black,
indicatorColor: Colors.white,
tabBarTheme: TabBarTheme(),
),
/* initialRoute: '/',
onGenerateRoute: RouteGenerator.generateRoute, */
builder: (context, child) {
return ScrollConfiguration(
behavior: MyBehavior(),
child: child!,
);
},
);

然后在需要引用的位置加入

import 'package:flutter_gen/gen_l10n/app_localizations.dart';

调用的位置

AppLocalizations.of(context)!.home_top_foryou

至此,国际化就完成了

另外本地针对播放模块进行了优化,将代码拆分到videoplayer.dart文件.一来是方便代码阅读,而来可以作为子组件使用,其他的代码写得太冗余也在继续拆开,独立出来,各位感兴趣的可以关注项目的进展。

采用FutureBuilder对界面请求数据异步处理,当加载完成后才播放,效果更佳

代码如下:

return FutureBuilder<DTok>(
future: videos,
builder: (context, snapshot) {
print(snapshot.connectionState);
if (snapshot.connectionState == ConnectionState.waiting) {
return loading;
// return Column(
// crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// loading,
// Visibility(
// visible: snapshot.hasData,
// child: PageView.builder(
// controller: foryouController,
// onPageChanged: (index) {
// //when the video is changing, release the previous video instance.
// //disposeVideo();
// setState(() {});
// },
// scrollDirection: Axis.vertical,
// itemCount: snapshot.data!.itemList!.length,
// itemBuilder: (context, index) {
// var item = snapshot.data!.itemList![index];
// return Videoplayer(
// item: item,
// width: MediaQuery.of(context).size.width,
// heigth: MediaQuery.of(context).size.height,
// );
// }),
// )
// ],
// );
} else if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Error, Please restart your app agagin')
],
);
} else if (snapshot.hasData) {
try {
return PageView.builder(
controller: foryouController,
onPageChanged: (index) {
//when the video is changing, release the previous video instance.
//disposeVideo();
//setState(() {});
},
scrollDirection: Axis.vertical,
itemCount: snapshot.data!.itemList!.length,
itemBuilder: (context, index) {
var item = snapshot.data!.itemList![index];
return Videoplayer(
item: item,
width: MediaQuery.of(context).size.width,
heigth: MediaQuery.of(context).size.height,
);
});
} catch (e) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.black,
child: Center(
child: Text(
'Error, Please restart your app again.',
style: TextStyle(color: Colors.white),
)),
);
}
} else {
// empty data
return loading;
}
} else {
return Text('State: ${snapshot.connectionState}');
}
});

这里可以看到当snapshot.connectionState == ConnectionState.waiting的时候请求的数据正在加载中,则显示加载的图标loading

当snapshot.connectionState == ConnectionState.done 时,此时数据已经加载完毕,但是加载完毕有可能也没有数据,所以需要判断不同的情况

当加载出现异常情况则显示异常的widget

if (snapshot.hasError) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Error, Please restart your app agagin')
],
);
}

当if (snapshot.hasData)则说明有返回值,但是这个返回值不一定就是我们需要的数据,所以还需要try catch一下,保证呈现给用户的界面是正常的

try {
return PageView.builder(
controller: foryouController,
onPageChanged: (index) {
//when the video is changing, release the previous video instance.
//disposeVideo();
//setState(() {});
},
scrollDirection: Axis.vertical,
itemCount: snapshot.data!.itemList!.length,
itemBuilder: (context, index) {
var item = snapshot.data!.itemList![index];
return Videoplayer(
item: item,
width: MediaQuery.of(context).size.width,
heigth: MediaQuery.of(context).size.height,
);
});
} catch (e) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.black,
child: Center(
child: Text(
'Error, Please restart your app again.',
style: TextStyle(color: Colors.white),
)),
);
}
}

其他情况则返回加载状态,因为没有数据返回

另外加载videoplay的时候把width、heigth传入到下一个控件,这样好计算界面呈现的宽度与高度

return Videoplayer(
item: item,
width: MediaQuery.of(context).size.width,
heigth: MediaQuery.of(context).size.height,
);

结语

请继续关注本博客,其他页面持续更新完成,源码地址:telsavideo, 欢迎fork和star,谢谢!!!

再次奉上演示地址:

前端地址:https://www.pgyer.com/dtok

后端服务器地址:http://47.95.209.198:8181/

第五篇- 抖音的强大对手来了,用Flutter手撸一个抖音国际版,看看有多炫的更多相关文章

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

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

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

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

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

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

  4. 五分钟,手撸一个Spring容器!

    大家好,我是老三,Spring是我们最常用的开源框架,经过多年发展,Spring已经发展成枝繁叶茂的大树,让我们难以窥其全貌. 这节,我们回归Spring的本质,五分钟手撸一个Spring容器,揭开S ...

  5. 【手撸一个ORM】第五步、Expression(表达式目录树)转换为Where子句

    说明 在SQL中,查询.修改比较常用到WHERE子句,在这里根据使用场景不同,定义了两个类,一个用于查询,一个用于修改(插入)操作.原因是: 查询操作支持一级导航属性查询,如student.Schoo ...

  6. 第五篇 SQL Server安全架构和安全

    本篇文章是SQL Server安全系列的第五篇,详细内容请参考原文. 架构本质上是一个数据库对象,其他对象的一个容器,在复杂的数据库中它能够很容易的管理各组对象.架构具有重要的安全功能.在这一篇你会学 ...

  7. 【译】第五篇 SQL Server安全架构和安全

    本篇文章是SQL Server安全系列的第五篇,详细内容请参考原文. 架构本质上是一个数据库对象,其他对象的一个容器,在复杂的数据库中它能够很容易的管理各组对象.架构具有重要的安全功能.在这一篇你会学 ...

  8. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  9. 【Python五篇慢慢弹(4)】模块异常谈python

    模块异常谈python 作者:白宁超 2016年10月10日12:08:31 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondo ...

随机推荐

  1. Supervisor多进程管理 异常自动重启 可视化管理

    一.序言 Supervisor是多进程管理工具,在Docker中相关联的进程能够通过supervisor来管理. 微服务项目开发阶段,可用于微服务子项目的启动管理. 支持web可视化管理,能够极大方面 ...

  2. Android 12(S) 图形显示系统 - createSurface的流程(五)

    题外话 刚刚开始着笔写作这篇文章时,正好看电视在采访一位92岁的考古学家,在他的日记中有这样一句话,写在这里与君共勉"不要等待幸运的降临,要去努力的掌握知识".如此朴实的一句话,此 ...

  3. 【微服务】- SpringCloud中Config、Bus和Stream

    文章目录 SpringCloud中Config 1.Config的简介 官网 分布式系统面临的问题 config是什么 如何使用 能做什么 与git的配合使用 2.Config服务端的配置和测试 准备 ...

  4. git命令log与reflog的比较

    感谢原文作者:杨鲜生 原文链接:https://blog.csdn.net/u013252047/article/details/80230781 用git命令,想看到自己的操作记录,则可以使用log ...

  5. java命令- (学习)jps

    jps(Java Virtual Machine Process Status Tool) 是java提供的一个显示当前所有java进程pid的命令,适合在linux/unix平台上简单察看当前jav ...

  6. 直播流媒体ums

    准备工具 下载  UltrantMediaServer服务器 FlashMediaLiveEncoder测试直播工具 第一步 安装 UltrantMediaServer服务器 第二步 打开网也输入   ...

  7. MyBatis加强(1)~缓存机制(一级缓存、二级缓存、第三方缓存技术redis、ehcache)

    一.缓存机制 使用缓存可以使应用更快地获取数据,避免频繁的数据库交互操作,尤其是在查询越多,缓存命中率越高 的情况下,缓存的作用就越明显. 1.缓存原理:Map ■ 查询时,先从缓存区查询:找到,返回 ...

  8. (一)什么是Rabbitmq

    1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式: 同步通讯:就像打电话,需要实时响应. 异步通讯:就像发邮件,不需要马上回复. 两种方式各有优劣,打电话可以立即得到响应,但是你 ...

  9. Vue.use初探

    Vue.use 问题 相信很多人在用Vue使用别人的组件时,会用到 Vue.use(). 例如:Vue.use(VueRouter).Vue.use(MintUI). 但是用 axios时,就不需要用 ...

  10. Solution -「洛谷 P5827」点双连通图计数

    \(\mathcal{Description}\)   link.   求有 \(n\) 个结点的点双连通图的个数,对 \(998244353\) 取模.   \(n\le10^5\). \(\mat ...