使用Flutter開(kāi)發(fā)的抖音國(guó)際版實(shí)例代碼詳解
簡(jiǎn)介
最近花了兩天時(shí)間研究使用Flutter開(kāi)發(fā)一個(gè)抖音國(guó)際版. 個(gè)人感覺(jué)使用Flutter開(kāi)發(fā)app快得不要不要的額. 兩天就基本可以開(kāi)發(fā)個(gè)大概出來(lái). 最主要是熱重載,太方便實(shí)時(shí)調(diào)整UI布局了. 相應(yīng)速度極快. 如下圖:
主要項(xiàng)目架構(gòu)
詳細(xì)說(shuō)明一下,開(kāi)發(fā)主要在lib文件夾
- pubspec.yaml是配置插件的位置,如http: ^0.12.0+4,類似依賴組件.
- common文件夾存放的是重寫的網(wǎng)絡(luò)組件,以及圖標(biāo)組件icons.dart
- config文件夾存放的api.dart,wei調(diào)用的api配置文件
- models文件存放的實(shí)體層
- screen文件夾存放的頁(yè)面view層
- tabs存放的底部切換文件夾層
- widgets存放的組件,包含視頻播放組件player.dart以及左右等描述組件
功能介紹
主要的依賴組件,請(qǐng)使用國(guó)內(nèi)鏡像下載,切記切記!?。?!
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
包含字體文件,主要為抖音自帶的字體文件
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開(kāi)發(fā)安卓、IOS等 app確實(shí)方便,主要為將tiktok的數(shù)據(jù)使用http下載下來(lái).
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層
主要為實(shí)體層,解析json后綁定數(shù)據(jù)以及傳遞數(shù)據(jù)
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; } }
視圖層
另外屏幕層主要包含三個(gè),homescreen,trendingscreen,以及顯示videoscreen
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轉(zhuǎn)化成實(shí)體對(duì)象,綁定數(shù)據(jù)到videoscreen頁(yè)面
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主要為綁定數(shù)據(jù). 展示抖音的視頻
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), ), ), ); }
此次開(kāi)發(fā)主要時(shí)間用在搭建Flutter環(huán)境上,切記使用國(guó)內(nèi)鏡像,另外調(diào)式需要配合代理即可。
其他待完成的包含底部的導(dǎo)航頁(yè)面,打算花兩天時(shí)間把剩余的完成.
各位感興趣的可以到我的github上點(diǎn)一下star. 留言可以教你們開(kāi)發(fā)以及搭建dart環(huán)境. 地址:https://github.com/WangCharlie/douyin
總結(jié)
到此這篇關(guān)于使用Flutter開(kāi)發(fā)的抖音國(guó)際版的文章就介紹到這了,更多相關(guān)flutter抖音國(guó)際版內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Flutter進(jìn)階之實(shí)現(xiàn)動(dòng)畫效果(一)
- Flutter 超實(shí)用簡(jiǎn)單菜單彈出框 PopupMenuButton功能
- flutter InkWell實(shí)現(xiàn)水波紋點(diǎn)擊效果
- 詳解Flutter WebView與JS互相調(diào)用簡(jiǎn)易指南
- Flutter持久化存儲(chǔ)之?dāng)?shù)據(jù)庫(kù)存儲(chǔ)(sqflite)詳解
- Flutter中如何加載并預(yù)覽本地的html文件的方法
- flutter日期選擇器 flutter時(shí)間選擇器
- Flutter啟動(dòng)頁(yè)(閃屏頁(yè))的具體實(shí)現(xiàn)及原理詳析
- 詳解flutter之網(wǎng)絡(luò)請(qǐng)求dio,請(qǐng)求,攔截器簡(jiǎn)單示例
- Flutter實(shí)現(xiàn)抖音點(diǎn)贊效果
相關(guān)文章
Android自定義gridView仿頭條頻道拖動(dòng)管理功能
這篇文章主要介紹了Android自定義gridView仿頭條頻道拖動(dòng)管理功能,本文通過(guò)實(shí)例代碼效果圖展示給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12Android編程開(kāi)發(fā)之Spinner組件用法
這篇文章主要介紹了Android編程開(kāi)發(fā)之Spinner組件用法,結(jié)合實(shí)例形式分析介紹了Android中Spinner組件的功能、定義及具體使用技巧,需要的朋友可以參考下2015-12-12學(xué)習(xí)使用Material Design控件(二)使用DrawerLayout實(shí)現(xiàn)側(cè)滑菜單欄效果
這篇文章主要為大家介紹了學(xué)習(xí)使用Material Design控件的詳細(xì)教程,使用DrawerLayout和NavigationView實(shí)現(xiàn)側(cè)滑菜單欄效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07Android實(shí)現(xiàn)兩圓點(diǎn)之間來(lái)回移動(dòng)加載進(jìn)度
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)兩圓點(diǎn)之間來(lái)回移動(dòng)加載進(jìn)度,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06漂亮的Android音樂(lè)歌詞控件 仿網(wǎng)易云音樂(lè)滑動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了漂亮的Android音樂(lè)歌詞控件,仿網(wǎng)易云音樂(lè)滑動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01Android實(shí)現(xiàn)輸入法彈出時(shí)把布局頂上去和登錄按鈕頂上去的解決方法
這篇文章主要介紹了Android實(shí)現(xiàn)輸入法彈出時(shí)把布局頂上去和登錄按鈕頂上去的解決方法,需要的朋友可以參考下2017-11-11深入解析Android中的setContentView加載布局原理
在日常開(kāi)發(fā)Android中setContentView是必不可少的一部分,下面這篇文章主要給大家介紹了關(guān)于Android中setContentView的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)下吧。2017-09-09