iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 2
1
Mobile Development

新手試試用Flutter做Netflix UI系列 第 2

[Day2]Flutter使用AnimatedContainer顯示啟動畫面

  • 分享至 

  • xImage
  •  

大家好,前一篇文章我們已經可以顯示圖片了。Flutter中的動畫方式有很多,今天我準備用AnimatedContainer來讓它改變透明度以及大小。

測試畫面

根據官方文件的敘述,AnimatedContainer將自動在屬性的舊值和新值之間設置動畫,並且會按照設定好的曲線(Curve)以及時間(Duration),大家可以參考AnimatedContainer

點擊改變透明度

先讓我們來加入透明度變化,使用AnimatedOpacity,基本上每一個這樣的Widget都必須帶duration,它會讓數值變化在這個時間完成,並且根據不同Curve給他不同插值方式。

class _SplashScreenPageState extends State<SplashScreenPage> {
double logoOpacity = 1.0;

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.black,
    body: Center(
      child: AnimatedOpacity(
          opacity: logoOpacity,
          duration: Duration(milliseconds: 500),
          child: Image.asset("assets/netflix_logo.png")),
    ),
  );
}
}

控制方式其實很簡單,只要更新我們的logoOpacity變數的值就行了。
我們可以先Wrap一個手勢判斷做個點擊測試一下,參考GestureDetecter
(使用command + Enter 可以快速移除那一層Widget或在外面再包一個Widget)

Center(
      child: GestureDetector(
        onTap: (){
        //點擊時,改變值並通知需要更新UI
          setState(() {
            logoOpacity = 0.0;
          });
        },
        child: AnimatedOpacity(
            opacity: logoOpacity,
            duration: Duration(milliseconds: 500),
            child: Image.asset("assets/netflix_logo.png")),
      ),
    )

opacity不能為null,且必須在0.0至1.0之間。
點擊之後讓logoPacity為0.0,不要忘了來個setState,不然它不會動的。

開啟畫面馬上播放漸變動畫

目前為止,我們點擊可以讓他正常消失,那如何讓它在一開啟App就自動消失呢?
我們可以在initState裡做一些事,這些事情會發生在first build 之前。
詳細Flutter生命週期可以參考這篇Flutter從啟動到顯示

 @override
void initState() {
  super.initState();
  //不起作用
  setState(() {
    logoOpacity = 0.0;
  });

  //方法一 在畫面第一次build之後,讓logoOpacity改變,似乎不理想
  WidgetsBinding.instance.addPostFrameCallback((timeStamp) {   
      logoOpacity = 0.0;
  });

  //方法二 建立一個延遲`Future`任務,讓它在一秒之後執行
  Future.delayed(Duration(seconds: 1), () {
    setState(() {
      logoOpacity = 0.0;
    });
  });
}

如果直接在initState進行setState是不會有作用的。
方法一,我想使用addPostFrameCallback,但是app第一次build之後就開始動畫,產生App剛產生畫面,動畫已經播完的情況.(我通常使用addPostFrameCallback在進入畫面就要顯示一個Dialog的情境)
方法二,使用延遲任務就比較沒問題,點開App一秒之後再讓logo漸變消失

改變透明度跟大小同時動畫

基於前面的測試,再加入大小變化是不是也沒那麼難了呢!我們使用AnimatedContainer控制大小,並加入Boolean startAnimation來判斷我們什麼時候要開始動畫

class _SplashScreenPageState extends State<SplashScreenPage> {
  bool startAnimation = false;

  @override
  void initState() {
    super.initState();
    //方法二
    Future.delayed(Duration(seconds: 1), () {
      setState(() {
        startAnimation = true;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: Center(
        child: AnimatedOpacity(
            opacity: startAnimation ? 0.0 : 1.0,
            duration: Duration(milliseconds: 2000),
            child: AnimatedContainer(
                duration: Duration(milliseconds: 2000),
                width: startAnimation ? 150.0 : 250.0,
                child: Image.asset("assets/netflix_logo.png"))),
      ),
    );
  }
}

今天的進度就到這邊,下一篇我們來進入主頁面!

GitHub連結: flutter-netflix-clone


上一篇
[Day1]建立Flutter專案製作第一個啟動頁面吧!
下一篇
[Day3]Flutter使用Column以及Row初步建立主頁面之推薦區
系列文
新手試試用Flutter做Netflix UI30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言