简介
最近花了两天时间研究使用Flutter开发一个抖音国际版. 个人感觉使用Flutter开发app快得不要不要的额. 两天就基本可以开发个大概出来. 最主要是热重载,太方便实时调整UI布局了. 相应速度极快. 如下图:
主要项目架构
详细说明一下,开发主要在lib文件夹
- pubspec.yaml是配置插件的位置,如http: ^0.12.0+4,类似依赖组件.
- common文件夹存放的是重写的网络组件,以及图标组件icons.dart
- config文件夹存放的api.dart,wei调用的api配置文件
- models文件存放的实体层
- screen文件夹存放的页面view层
- tabs存放的底部切换文件夹层
- widgets存放的组件,包含视频播放组件player.dart以及左右等描述组件
功能介绍
主要的依赖组件,请使用国内镜像下载,切记切记!!!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
flutter: sdk: flutter flutter_svg: ^ 0.17 . 4 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^ 0.1 . 3 cached_network_image: ^ 2.2 . 0 json_annotation: ^ 3.0 . 1 font_awesome_flutter: ^ 8.8 . 1 http: ^ 0.12 . 0 + 4 provider: ^ 4.0 . 4 avatar_glow: any getflutter: ^ 1.0 . 11 flutter_money_formatter: ^ 0.8 . 3 video_player: ^ 0.10 . 8 + 1 dio: ^ 3.0 . 9 dio_cookie_manager: ^ 1.0 . 0 |
包含字体文件,主要为抖音自带的字体文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import 'package:flutter/widgets.dart' ; class DouyinIcons { DouyinIcons._(); static const _kFontFam = 'DouyinIcons' ; static const IconData chat_bubble = const IconData( 0xe808 , fontFamily: _kFontFam); static const IconData create = const IconData( 0xe809 , fontFamily: _kFontFam); static const IconData heart = const IconData( 0xe80a , fontFamily: _kFontFam); static const IconData home = const IconData( 0xe80b , fontFamily: _kFontFam); static const IconData messages = const IconData( 0xe80c , fontFamily: _kFontFam); static const IconData profile = const IconData( 0xe80d , fontFamily: _kFontFam); static const IconData reply = const IconData( 0xe80e , fontFamily: _kFontFam); static const IconData search = const IconData( 0xe80f , fontFamily: _kFontFam); } |
此次采用Flutter开发安卓、IOS等 app确实方便,主要为将tiktok的数据使用http下载下来.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import 'package:http/http.dart' as http; class RequestController { static String host = "https://www.tiktok.com/" ; String url = host + "/share/item/list?secUid=&id=&type=5&count=30&minCursor=0&maxCursor=0&shareUid=&lang=en&_signature=pKb.ogAgEB9ImoSQahoqJKSm.rAAPox" ; Future<String> getCookie() async { try { var response = await http.get(host + "/share/item/" ); return response.headers[ "set-cookie" ]; } catch (e) { return "error" ; } } |
Model层
主要为实体层,解析json后绑定数据以及传递数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
class Tiktok { int statueCode; Body body; Object errMsg; Tiktok({ this .statueCode, this .body, this .errMsg}); Tiktok.fromJson(Map<String, dynamic> json) { statueCode = json[ 'statusCode' ]; body = json[ 'body' ] != null ? new Body.fromJson(json[ 'body' ]) : null ; errMsg = json[ 'errMsg' ]; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); data[ 'statusCode' ] = this .statueCode; if ( this .body != null ) { data[ 'body' ] = this .body.toJson(); } data[ 'errMsg' ] = this .errMsg; return data; } } |
视图层
另外屏幕层主要包含三个,homescreen,trendingscreen,以及显示videoscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
import 'package:flutter/material.dart' ; import 'package:flutter_app/Screens/trendingScreen.dart' ; import 'package:flutter_app/widgets/bottom_toolbar.dart' ; class Home extends StatefulWidget { @override HomeState createState() => HomeState(); } class HomeState extends State<Home> { int currentIndex = 0 ; PageController pageController; @override Widget build(BuildContext context) { return Scaffold( body: PageView( controller: pageController, children: <Widget>[ Trending(), ], onPageChanged: ( int index) { setState(() { currentIndex = index; }); }, ), bottomNavigationBar: bottomItems(currentIndex, pageController), ); } } |
Tending层,主要包含读取抖音的api,将api转化成实体对象,绑定数据到videoscreen页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
import 'dart:convert' ; import 'package:flutter/material.dart' ; import 'package:flutter/cupertino.dart' ; import 'package:getflutter/getflutter.dart' ; import 'package:flutter_app/config/api.dart' ; import 'package:flutter_app/models/Tiktok.dart' ; import 'package:http/http.dart' as http; import 'package:flutter_app/Screens/videoScreen.dart' ; class Trending extends StatefulWidget { _TrendingState createState() => _TrendingState(); } class _TrendingState extends State<Trending> { PageController pageController; BuildContext context; RequestController api = RequestController(); List<Widget> videos = []; getTrending() async { var cookies = await api.getCookie(); api.setCookie(cookies); try { var response = await http.get( api.url, headers: api.headers, ); Tiktok tiktok = Tiktok.fromJson(jsonDecode(response.body)); tiktok.body.itemListData.forEach( (item) { setState(() { videos.add(VideoItem(data: item)); }); }, ); } catch (ex) { SimpleDialog( title: Text( 'Hot videos list is empty' ), ); print(ex); } } @override void initState() { super .initState(); getTrending(); } @override Widget build(BuildContext context) { context = context; return PageView( scrollDirection: Axis.vertical, controller: pageController, children: videos.length == 0 ? <Widget>[ Container( color: Colors.black, child: Center( child: GFLoader( type: GFLoaderType.circle, loaderColorOne: Colors.blueAccent, loaderColorTwo: Colors.white, loaderColorThree: Colors.pink, ), ), ) ] : videos, ); } } |
VideoScreen主要为绑定数据. 展示抖音的视频
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
import 'package:flutter/material.dart' ; import 'package:flutter_app/models/Tiktok.dart' ; import 'package:flutter_app/widgets/video_description.dart' ; import 'package:flutter_app/widgets/actions_toolbar.dart' ; import 'package:flutter_app/widgets/player.dart' ; class VideoItem extends StatelessWidget { final ItemListData data; const VideoItem({ @required this .data}); @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: <Widget>[ DouyinVideoPlayer( url: data.itemInfos.video.urls[ 0 ], ), title(), VideoDescription( description: data.itemInfos.text, musicName: data.musicInfos.musicName, authorName: data.musicInfos.authorName, userName: data.authorInfos.uniqueId, ), ActionsToolbar( comments: data.itemInfos.commentCount.toString(), userImg: data.authorInfos.covers[ 0 ], favorite: data.itemInfos.diggCount, coverImg: data.musicInfos.covers[ 0 ], ), ], ), ); } Widget title() => Align( alignment: Alignment.topCenter, child: Padding( padding: EdgeInsets.symmetric(vertical: 28.0 ), child: Text( "Trending | For You" , style: TextStyle(color: Colors.white, fontSize: 19.0 ), ), ), ); } |
此次开发主要时间用在搭建Flutter环境上,切记使用国内镜像,另外调式需要配合代理即可。
其他待完成的包含底部的导航页面,打算花两天时间把剩余的完成.
各位感兴趣的可以到我的github上点一下star. 留言可以教你们开发以及搭建dart环境. 地址:https://github.com/WangCharlie/douyin
总结
到此这篇关于使用Flutter开发的抖音国际版的文章就介绍到这了,更多相关flutter抖音国际版内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://www.cnblogs.com/fengqingyangNo1/p/12927538.html