zoukankan      html  css  js  c++  java
  • 使用Flutter开发的抖音国际版

    摘自:https://www.cnblogs.com/fengqingyangNo1/p/12927538.html

    简介

    最近花了两天时间研究使用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
    复制代码

    包含字体文件,主要为抖音自带的字体文件

    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
    69
    70
    71
    72
    73
    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
    45
    46
    47
    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

    感兴趣的各位留言哈. 

    作者:风清扬 No.1
    出处:http://www.cnblogs.com/fengqingyangNo1


    如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】按钮。
    如果,您希望更容易地发现我的新博客,不妨点击一下右下角的 【关注 风清扬 No.1】。
    因为,我的写作热情也离不开您的肯定支持。


    感谢您的阅读,如果您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客.
     
     
  • 相关阅读:
    [转]为什么匿名内部类参数必须为final类型
    [转]软件开发规范—模块开发卷宗(GB8567——88)
    [转]概要设计与详细设计的区别
    [转]解析UML建模语言中的UML图分类、 UML各种图形及作用
    python mysql插入中文乱码
    pycharm mysql数据源配置、SQL方言配置
    pycharm批量查找替换,正则匹配
    python第三方库安装
    什么是Vagrant
    python读写excel文件
  • 原文地址:https://www.cnblogs.com/xichji/p/12935026.html
Copyright © 2011-2022 走看看