• 使用Flutter开发的抖音国际版


    简介

    最近花了两天时间研究使用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以及左右等描述组件

    功能介绍

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

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

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

     

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

    感兴趣的各位留言哈. 

  • 相关阅读:
    pycharm安装破解
    flask动态生成csv
    使用django开发restful接口
    python matplotlib显示中文和负数符号
    locust性能测试02—检查点
    locust性能测试01—初体验
    Mac中配置jmeter+grafana监控
    CF731E Funny Game
    CF197A Plate Game
    luoguP1823 [COI2007] Patrik 音乐会的等待
  • 原文地址:https://www.cnblogs.com/fengqingyangNo1/p/12927538.html
Copyright © 2020-2023  润新知