使用Flutter开发的抖音国际版实例代码详解

作者:风清扬 No.1 时间:2023-11-12 09:38:44 

简介

最近花了两天时间研究使用Flutter开发一个抖音国际版. 个人感觉使用Flutter开发app快得不要不要的额. 两天就基本可以开发个大概出来. 最主要是热重载,太方便实时调整UI布局了. 相应速度极快. 如下图:

使用Flutter开发的抖音国际版实例代码详解

主要项目架构

使用Flutter开发的抖音国际版实例代码详解

详细说明一下,开发主要在lib文件夹

  • pubspec.yaml是配置插件的位置,如http: ^0.12.0+4,类似依赖组件.

  • common文件夹存放的是重写的网络组件,以及图标组件icons.dart

  • config文件夹存放的api.dart,wei调用的api配置文件

  • models文件存放的实体层

  • screen文件夹存放的页面view层

  • tabs存放的底部切换文件夹层

  • widgets存放的组件,包含视频播放组件player.dart以及左右等描述组件

功能介绍

主要的依赖组件,请使用国内镜像下载,切记切记!!!!


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开发安卓、IOS等 app确实方便,主要为将tiktok的数据使用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后绑定数据以及传递数据


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转化成实体对象,绑定数据到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主要为绑定数据. 展示抖音的视频


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环境上,切记使用国内镜像,另外调式需要配合代理即可。

其他待完成的包含底部的导航页面,打算花两天时间把剩余的完成.

使用Flutter开发的抖音国际版实例代码详解

各位感兴趣的可以到我的github上点一下star. 留言可以教你们开发以及搭建dart环境. 地址:https://github.com/WangCharlie/douyin

来源:https://www.cnblogs.com/fengqingyangNo1/p/12927538.html

标签:flutter,抖音,国际版
0
投稿

猜你喜欢

  • C# 装箱和拆箱的知识回顾

    2022-07-19 09:27:58
  • Trie树(字典树)的介绍及Java实现

    2022-06-14 15:38:24
  • windows下java -jar 后台运行以及杀死后台进程的操作

    2022-02-09 17:28:13
  • IDEA不编译除了.java之外的文件的解决办法(推荐)

    2023-09-16 15:50:44
  • Java实现马踏棋盘算法

    2023-03-05 04:30:46
  • Android用户输入自动提示控件AutoCompleteTextView使用方法

    2022-02-25 14:59:50
  • C#中后台post请求常用的两种方式总结

    2023-04-21 17:29:40
  • 浅谈C#中的委托、事件与异步

    2022-04-25 23:05:34
  • Java 非阻塞I/O使用方法

    2022-01-01 22:54:57
  • java GUI编程之监听操作实例分析

    2022-09-28 05:55:53
  • Spring Cloud Gateway整合sentinel 实现流控熔断的问题

    2022-01-18 23:10:05
  • Android中EditText光标在4.0中的bug及解决方法

    2023-10-01 19:24:17
  • Android自定义View实现五子棋游戏

    2021-12-25 19:32:55
  • C#中事件只能在内部调用的原因分析

    2023-08-09 05:07:00
  • Java之int和string类型转换详解

    2023-11-06 04:10:06
  • SpringBoot关于自定义注解实现接口幂等性方式

    2023-09-27 14:03:42
  • Java设计模式之Strategy模式

    2023-11-21 03:58:22
  • 基于Java实现Actor模型

    2021-12-11 09:28:50
  • 分析HashMap 的 JDK 源码

    2022-01-17 06:29:54
  • C语言实现顺序表的顺序查找和折半查找

    2021-10-24 13:17:19
  • asp之家 软件编程 m.aspxhome.com