使用Flutter開發(fā)的抖音國際版實例代碼詳解
簡介
最近花了兩天時間研究使用Flutter開發(fā)一個抖音國際版. 個人感覺使用Flutter開發(fā)app快得不要不要的額. 兩天就基本可以開發(fā)個大概出來. 最主要是熱重載,太方便實時調(diào)整UI布局了. 相應(yīng)速度極快. 如下圖:

主要項目架構(gòu)

詳細說明一下,開發(fā)主要在lib文件夾
- pubspec.yaml是配置插件的位置,如http: ^0.12.0+4,類似依賴組件.
- common文件夾存放的是重寫的網(wǎng)絡(luò)組件,以及圖標組件icons.dart
- config文件夾存放的api.dart,wei調(diào)用的api配置文件
- models文件存放的實體層
- screen文件夾存放的頁面view層
- tabs存放的底部切換文件夾層
- widgets存放的組件,包含視頻播放組件player.dart以及左右等描述組件
功能介紹
主要的依賴組件,請使用國內(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開發(fā)安卓、IOS等 app確實方便,主要為將tiktok的數(shù)據(jù)使用http下載下來.
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后綁定數(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;
}
}
視圖層
另外屏幕層主要包含三個,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ù)據(jù)到videoscreen頁面
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),
),
),
);
}
此次開發(fā)主要時間用在搭建Flutter環(huán)境上,切記使用國內(nèi)鏡像,另外調(diào)式需要配合代理即可。
其他待完成的包含底部的導(dǎo)航頁面,打算花兩天時間把剩余的完成.

各位感興趣的可以到我的github上點一下star. 留言可以教你們開發(fā)以及搭建dart環(huán)境. 地址:https://github.com/WangCharlie/douyin
總結(jié)
到此這篇關(guān)于使用Flutter開發(fā)的抖音國際版的文章就介紹到這了,更多相關(guān)flutter抖音國際版內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Flutter進階之實現(xiàn)動畫效果(一)
- Flutter 超實用簡單菜單彈出框 PopupMenuButton功能
- flutter InkWell實現(xiàn)水波紋點擊效果
- 詳解Flutter WebView與JS互相調(diào)用簡易指南
- Flutter持久化存儲之?dāng)?shù)據(jù)庫存儲(sqflite)詳解
- Flutter中如何加載并預(yù)覽本地的html文件的方法
- flutter日期選擇器 flutter時間選擇器
- Flutter啟動頁(閃屏頁)的具體實現(xiàn)及原理詳析
- 詳解flutter之網(wǎng)絡(luò)請求dio,請求,攔截器簡單示例
- Flutter實現(xiàn)抖音點贊效果
相關(guān)文章
Android自定義View實現(xiàn)圓弧進度效果逐步完成過程
在Android開發(fā)中,通過自定義View實現(xiàn)自己想要的效果是作為android開發(fā)程序員的一項必備技能,自定義View對于android開發(fā)來說也是比較難的一項技術(shù)2023-04-04
Android利用ShaderMask實現(xiàn)花里胡哨的文字特效
我們的?App?大部分時候的文字都是一種顏色,實際上,文字的顏色也可以多姿多彩。我們今天就來介紹一個能夠輕松實現(xiàn)文字漸變色的組件?——?ShaderMask,感興趣的可以了解一下2022-12-12
Android SDK 百度地圖通過poi城市內(nèi)檢索簡介接口的使用
這篇文章主要介紹了Android SDK 百度地圖通過poi城市內(nèi)檢索簡介接口的使用的相關(guān)資料,需要的朋友可以參考下2016-02-02
20.5 語音合成(百度2016年2月29日發(fā)布的tts引擎)
編寫手機App時,有時需要使用文字轉(zhuǎn)語音(Text to Speech)的功能,比如開車時閱讀收到的短信、導(dǎo)航語音提示、界面中比較重要的信息通過語音強調(diào)2016-03-03
Android小掛件(APP Widgets)設(shè)計指導(dǎo)
這篇文章主要為大家詳細介紹了Android小掛件APP Widgets設(shè)計指導(dǎo),具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-12-12

