第三篇-用Flutter手擼一個抖音國內版,看看有多炫


前言

前一篇已經開發了大部分框架,包含視頻上下滑動播放,這次將上次未完成的數據顯示友好顯示,以及底部音樂走馬燈特效,另外優化了加載數據的bug,在dart語言里 & 會自動變成&  另外優化了代碼邏輯.

本系列會持續更新,將各個模塊及功能持續完善,地址:https://github.com/WangCharlie/douyin  歡迎各位fork 和star. 謝謝!

運行效果如下圖:

 

修復Dart語言 URL顯示錯誤.

經過反復則是,發現url 在tostring()方法執行后 會把原來的 &替換成&amp,  所以暫時只能這樣替換了 url = url.replaceAll('&', '&')來修復問題了

  getVideos(BillboardData v) async {
    try {
      var url = v.link.split("/")[5];
      var response = await http.get(
        api.video + url + "&dytk",
        headers: api.headers,
      );
      VideoData videoData = VideoData.fromJson(jsonDecode(response.body));
      //獲取無水印的視頻地址
      api.getRedirects(videoData.itemList[0].video.playaddr.uri).then((url) => {
            url = url.replaceAll('&amp', '&'),
            if (url != '')
              {
                videos.add(VideoItem(
                  data: videoData,
                  videourl: url,
                )),
                //print(url),
              }
          });
    } catch (ex) {
      print(ex);
    }
  }

  

對數據友好格式化顯示

如下圖顯示數據通常超過1000 會顯示1k,超過10000顯示1m,這樣更加友好顯示數據.  主要使用了package:flutter_money_formatter 這個組件

 1,先引用 import 'package:flutter_money_formatter/flutter_money_formatter.dart';

 2,使用如下方法

    FlutterMoneyFormatter fmf =
        FlutterMoneyFormatter(amount: double.parse(widget.favorite.toString()));

    FlutterMoneyFormatter fmf2 =
        FlutterMoneyFormatter(amount: double.parse(widget.comments));

3,顯示的方法如下

fmf.output.compactNonSymbol

 

完整的實現代碼如下:

 return Align(
        alignment: Alignment.bottomRight,
        widthFactor: 100.0,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.end,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            _getFollowAction(),
            _getSocialAction(
                icon: DouyinIcons.heart,
                title: '${fmf.output.compactNonSymbol}'),
            _getSocialAction(
                icon: DouyinIcons.chat_bubble,
                title: '${fmf2.output.compactNonSymbol}'),
            _getSocialAction(
                icon: DouyinIcons.reply, title: '分享', isShare: true),
            _getMusicPlayerAction()
          ],
        ));
  }

底部音樂名字走馬燈特效

先引入 import 'package:marquee_widget/marquee_widget.dart';  

反復測試后發現,這里需要設置width,否則沒有效果,切記.  並使用container包含起來

              Container(
                width: 150,
                child: Marquee(
                  child: Text('${widget.musicName} - ${widget.authorName}'),
                  direction: Axis.horizontal,
                  textDirection: TextDirection.ltr,
                  animationDuration: Duration(seconds: 1),
                  directionMarguee: DirectionMarguee.oneDirection,
                ),
              ),
            ])

 

 

音樂圖標旋轉效果

 

這里主要模仿抖音的音樂按鈕旋轉起來的特效,目前還未實現的地方是哪個音樂字符飛出來消失 

改造后的代碼如下,先使用  SingleTickerProviderStateMixin,當元素顯示時才播放動畫效果

class _ActionsToolbarState extends State<ActionsToolbar>
    with SingleTickerProviderStateMixin {
  static const double ActionWidgetSize = 60.0;
  static const double ActionIconSize = 35.0;
  static const double ShareActionIconSize = 25.0;
  static const double ProfileImageSize = 50.0;
  static const double PlusIconSize = 20.0;
  AnimationController animationController;

 

然后設置初始化狀態,以及各種初始化參數。間隔 seconds: 5,並且在初始化狀態下把animationController 創建出來,下面的方法使用得到

  @override
  void initState() {
    super.initState();
    animationController = new AnimationController(
      vsync: this,
      duration: new Duration(seconds: 5),
    );
    animationController.repeat();
  }

 

這里是完整的播放圖標改造后的代碼

Widget _getMusicPlayerAction() {
    return Container(
        margin: EdgeInsets.only(top: 10.0),
        width: ActionWidgetSize,
        height: ActionWidgetSize,
        child: Column(children: [
          Container(
            decoration: new BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(25.0)),
              color: Colors.black54,
            ),
            padding: EdgeInsets.all(11.0),
            height: ProfileImageSize,
            width: ProfileImageSize,
            child: AnimatedBuilder(
              animation: animationController,
              child: Container(
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  gradient: musicGradient,
                  //border: Border.all(color: Colors.black87, width: 11.0),
                  image: DecorationImage(
                    image: NetworkImage(widget.coverImg),
                    fit: BoxFit.cover,
                  ),
                ),
              ),
              builder: (BuildContext context, Widget _widget) {
                return Transform.rotate(
                  angle: animationController.value * 6.3,
                  child: _widget,
                );
              },
            ),

            // decoration: BoxDecoration(
            //   shape: BoxShape.circle,
            //   gradient: musicGradient,
            //   border: Border.all(color: Colors.black87, width: 11.0),
            //   image: DecorationImage(
            //     image: NetworkImage(widget.coverImg),
            //     fit: BoxFit.cover,
            //   ),
            // ),
          ),
        ]));
  }

 未完成的還有搜索界面,消息頁面、關注,登錄界面,后續會繼續完善這些界面

結語

本博客會持續更新,將在業余時間將其他的功能完善。請持續關注本博客,代碼地址:https://github.com/WangCharlie/douyin

歡迎各位點擊star 和fork 代碼. 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM