前言
前一篇已經開發了大部分框架,包含視頻上下滑動播放,這次將上次未完成的數據顯示友好顯示,以及底部音樂走馬燈特效,另外優化了加載數據的bug,在dart語言里 & 會自動變成& 另外優化了代碼邏輯.
本系列會持續更新,將各個模塊及功能持續完善,地址:https://github.com/WangCharlie/douyin 歡迎各位fork 和star. 謝謝!
運行效果如下圖:

修復Dart語言 URL顯示錯誤.
經過反復則是,發現url 在tostring()方法執行后 會把原來的 &替換成&, 所以暫時只能這樣替換了 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('&', '&'),
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
