Flutter - 了解Flutter中的動畫

如果我們想要一些東西動畫颠放,我們必須改變大小或改變連續(xù)幀中對象的位置排惨。例如,在第1幀中碰凶,我們的對象位于位置x暮芭,在第2幀中,它將位于x + 1的位置欲低,在第3幀中辕宏,它位于x + 2的位置,依此類推砾莱。

創(chuàng)建動畫時(shí)的另一個(gè)概念是“每秒幀數(shù)”或FPS瑞筐。我們想要每秒更改對象的位置或大小多少次?電影通常每秒使用24幀腊瑟。這是人類眼睛看起來光滑自然的動畫的最小數(shù)量聚假。

FPS(圖片來源

為了在Flutter中為小部件設(shè)置動畫,我們需要以下小部件:

  1. Animation<T>:動畫對象由值(類型T)和狀態(tài)組成闰非。該值類似于當(dāng)前幀編號膘格。它會告訴您是否在第1,2,3等幀中。根據(jù)此值河胎,您可以決定窗口小部件的下一個(gè)位置或大小闯袒。狀態(tài)指示動畫在概念上是從開始到結(jié)束還是從結(jié)束回到開始。
  2. AnimationController:要創(chuàng)建動畫游岳,首先要創(chuàng)建一個(gè)AnimationController政敢。在給定的持續(xù)時(shí)間內(nèi),此小部件線性生成從0.0(下限)到1.0(上限)的值胚迫。只要運(yùn)行應(yīng)用程序的設(shè)備準(zhǔn)備好顯示新幀(通常喷户,此速率大約為每秒60個(gè)值),動畫控制器就會生成一個(gè)新值访锻。一個(gè)AnimationController當(dāng)不再需要它應(yīng)該被設(shè)置褪尝。這減少了泄漏的可能性闹获。當(dāng)與StatefulWidget一起使用時(shí),通常在State.initState方法中創(chuàng)建AnimationController 河哑,然后將其放置在State.dispose中避诽。方法。請注意璃谨,AnimationController繼承了Animation類沙庐,因此屬于Animation類型。
  3. Tween:這個(gè)類可用于將1AnimationController1的下界和上界(默認(rèn)值為0.0到1.0)從開始到結(jié)束轉(zhuǎn)換(或映射)到值佳吞。除非另有說明拱雏,否則吐Tween為double類型。補(bǔ)間的唯一工作是定義一個(gè)從輸入范圍到輸出范圍的映射底扳。輸入范圍通常是0.0到1.0铸抑,但這不是必需的。
  4. TickerProvider:這是一個(gè)生成Ticker對象的工廠衷模。Ticker對象為每個(gè)新幀觸發(fā)一個(gè)事件鹊汛。AnimationController類使用Ticker來逐步調(diào)整它控制的動畫。我們可以通過使用SingleTickerProviderStateMixin 實(shí)現(xiàn)TickerProvider功能算芯,將Ticker功能添加到我們的有狀態(tài)類中柒昏。如果您不確定mixins是什么,請閱讀本文熙揍。當(dāng)您只需要一個(gè)Ticker對象時(shí)(例如职祷,如果類在其整個(gè)生命周期內(nèi)僅創(chuàng)建一個(gè)AnimationController),此mixin非常有用届囚。
  5. AnimatedBuilder:很明顯有梆,每當(dāng)我們改變小部件的大小或位置時(shí),我們都想重新構(gòu)建它意系。但是我們怎么做到的泥耀?這是AnimatedBuilder小部件派上用場的地方。我們給這個(gè)小部件提供動畫蛔添,并告訴它在動畫前進(jìn)時(shí)要繪制什么痰催。

好吧,讓我們做一些實(shí)際的事迎瞧。

首先夸溶,我們將在屏幕中間創(chuàng)建一個(gè)圓圈,并使其周期性地變大凶硅。

我們的主要功能運(yùn)行應(yīng)用程序并顯示AnimatedCirclePage

main.dart

import 'package:animation/pages/animated_circle_page.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: AnimatedCirclePage(),
    );
  }
}

AnimatedCirclePage最初顯示在頁面中間的圓圈:

animated_circle_page.dart

import 'package:flutter/material.dart';

class AnimatedCirclePage extends StatefulWidget {
  @override
  _AnimatedCirclePageState createState() => _AnimatedCirclePageState();
}

class _AnimatedCirclePageState extends State<AnimatedCirclePage> {
@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Animated Circle"),
      ),
      body: Center(
        child: Container(
          width: 50,
          height: 50,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.all(
              Radius.circular(25),
            ),
            color: Colors.red,
          ),
        ),
      ),
    );
  }
}

現(xiàn)在讓我們用動畫放大這個(gè)圓圈缝裁。

在下面的代碼中,我們添加了一個(gè)類型的成員AnimationController并在initState方法中實(shí)例化它足绅。AnimationController需要兩個(gè)參數(shù):DurationTickerProvider捷绑。

duration參數(shù)指定動畫將持續(xù)多長時(shí)間韩脑,在我們的示例中,將需要1秒鐘才能完成粹污。

第二個(gè)參數(shù)被命名vsync為type TickerProvider段多。由于我們TickerProvider使用以下mixin為我們的類添加了功能:

with SingleTickerProviderStateMixin

該類的當(dāng)前實(shí)例可以vsync作為TickerProvider:傳遞給參數(shù):

vsync: this

因此我們將:

animated_circle_page.dart

class _AnimatedCirclePageState extends State<AnimatedCirclePage>
    with SingleTickerProviderStateMixin {
  
  AnimationController animationController;

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

調(diào)用該forward方法將啟動動畫并生成從0.0(下限)到1.0(上限)的值。但是我們?nèi)绾蜗纳傻膬r(jià)值呢壮吩?

使用AnimatedBuilder小部件衩匣!

animated_circle_page.dart

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Animated Circle"),
      ),
      body: AnimatedBuilder(
        animation: animationController,
        builder: (BuildContext context, Widget child) {
          final size = 100 * (animationController.value+1);
          return Center(
            child: Container(
              width: size,
              height: size,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.all(
                  Radius.circular(size/2),
                ),
                color: Colors.red,
              ),
            ),
          );
        },
      ),
    );
  }

AnimationBuilder的構(gòu)造函數(shù)有三個(gè)參數(shù):

  1. animation:我們在這里提供動畫對象。請記住粥航,AnimationController繼承自Animation類。因此生百,我們的AnimationController屬于Animation類型递雀,可以傳遞給此參數(shù)。
  2. child:此可選參數(shù)是一個(gè)小部件蚀浆,在動畫期間不會更改缀程,只創(chuàng)建一次(以提高性能)。它總是可以在構(gòu)建器函數(shù)(下一個(gè)參數(shù))中重用市俊。
  3. builder:這是為動畫的每個(gè)刻度調(diào)用的函數(shù)杨凑。在這里,我們可以決定在動畫的下一幀中繪制什么摆昧。我們可以通過animation.value屬性訪問當(dāng)前幀號撩满。

一旦我們調(diào)用該animationController.forward()方法,我們的動畫就會啟動绅你,并且將為動畫的每個(gè)幀調(diào)用AnimatedBuilder的構(gòu)建器方法伺帘。在每個(gè)幀中,值animationController.value將逐漸從0.0增加到1.0忌锯。我們可以利用這個(gè)值并根據(jù)它改變圓的寬度和高度:

final size = 100 * (animationController.value+1);

如您所見伪嫁,當(dāng)動畫值為0.0時(shí),圓的大小將為100偶垮,當(dāng)值增加到1.0時(shí)张咳,大小將更改為200.因此,我們必須看到以下動畫似舵,其中圓的大小從100變?yōu)?00到200:

擴(kuò)大圈

在上面的示例中脚猾,我們?yōu)樗袆赢嬛堤砑恿?。實(shí)際上啄枕,我們需要將動畫的范圍從[0.0 ... 1.0]更改為[1.0 ... 2.0]婚陪。你還記得這Tween堂課對什么有用嗎?它用于修改動畫值频祝。所以我們可以在這里使用Tween類將動畫值從[0.0 ... 1.0]映射到[1.0 ... 2.0]泌参。我們開始做吧:

animated_circle_page.dart

void initState() {
  super.initState();
  animationController = AnimationController(
    duration: Duration(
      seconds: 1,
    ),
    vsync: this,
  );
  animation = Tween(begin: 1.0, end: 2.0).animate(animationController);
  animationController.forward();
}

映射動畫值實(shí)際上發(fā)生在以下行中:

animation = Tween(begin:1.0, end:2.0).animate(animationController);

我們創(chuàng)建一個(gè)實(shí)例Tween并指定beginend值脆淹。然后我們調(diào)用該animate方法并將動畫對象傳遞給它。animate函數(shù)會返回一個(gè)新的animation對象沽一,其值是從beginend盖溺。然后在AnimatedBuilder對象中,我們只需將animation屬性設(shè)置為我們的新animation對象:

body: AnimatedBuilder(
  animation: animation,

并將圓的大小設(shè)置為:

final size = 100 * (animation.value);

反轉(zhuǎn)動畫

現(xiàn)在讓我們做一些有趣的事情铣缠。一旦我們的動畫完成烘嘱,我們將反轉(zhuǎn)動畫(這次它的值從1變?yōu)?)。這將使圓圈再次變小蝗蛙。

我們怎么知道我們的動畫是完整的蝇庭?

通過監(jiān)聽AnimationStatus

我們可以為動畫添加一個(gè)監(jiān)聽器捡硅,這樣每次狀態(tài)改變時(shí)哮内,我們都會收到通知。

animated_circle_page.dart

  @override
  void initState() {
    super.initState();
    animationController = AnimationController(
      duration: Duration(
        seconds: 1,
      ),
      vsync: this,
    );
    animation = Tween(begin: 1.0, end: 2.0).animate(animationController);

    animationController.addStatusListener(animationStatusListener);
    animationController.forward();
  }

  void animationStatusListener(AnimationStatus status) {
    if (status == AnimationStatus.completed) {
      animationController.reverse();
    } else if (status == AnimationStatus.dismissed) {
      animationController.forward();
    }
  }

只有在狀態(tài)發(fā)生變化時(shí)才會調(diào)用我們的偵聽器函數(shù)壮韭。動畫有四種可能的狀態(tài):

  1. dismissed動畫在開始時(shí)停止
  2. forward動畫從頭到尾運(yùn)行
  3. reverse動畫從頭到尾向后運(yùn)行
  4. completed動畫在結(jié)束時(shí)停止

在上面的代碼中北发,我們檢查了狀態(tài)。如果是completed喷屋,那意味著我們剛剛到達(dá)動畫的末尾琳拨,所以我們調(diào)用reverse函數(shù),向后播放動畫屯曹。當(dāng)狀態(tài)變?yōu)?code>dismissed狱庇,表示動畫已經(jīng)到達(dá)開頭,所以我們forward再次打電話恶耽!這個(gè)循環(huán)將永遠(yuǎn)持續(xù)下去僵井!

生成的動畫是一個(gè)連續(xù)大小的圓圈:

現(xiàn)在讓我們做一些更有趣的事情。我們將圍繞屏幕中心旋轉(zhuǎn)這個(gè)圓圈!

rotating_circle_page.dart使用以下代碼創(chuàng)建一個(gè)名為的新頁面:

import 'package:flutter/material.dart';

class RotatingCirclePage extends StatefulWidget {
  @override
  _RotatingCirclePageState createState() => _RotatingCirclePageState();
}

class _RotatingCirclePageState extends State<RotatingCirclePage>
    with SingleTickerProviderStateMixin {

  Widget _buildCircle(radius) {
    return Container(
      width: radius * 2,
      height: radius * 2,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.all(
          Radius.circular(radius),
        ),
        color: Colors.red,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Rotating Circle"),
      ),
      body: Align(
        alignment: Alignment(0, -0.1),
        child: _buildCircle(30.0),
      ),
    );
  }
}

為了使代碼更具可讀性,我創(chuàng)建了一個(gè)輔助函數(shù)_buildCircle拗小,用于繪制具有給定半徑的紅色圓圈蚪拦。而不是將圓圈居中,我將它對齊在頁面中心的上方。(如果您不熟悉,請觀看谷歌的這個(gè)簡短視頻以熟悉Align小部件)。結(jié)果是:

現(xiàn)在讓我們像鐘擺一樣為這個(gè)圓圈制作動畫:

animated_circle_page.dart

import 'package:flutter/material.dart';
import 'dart:math' as math;

class RotatingCirclePage extends StatefulWidget {
  @override
  _RotatingCirclePageState createState() => _RotatingCirclePageState();
}

class _RotatingCirclePageState extends State<RotatingCirclePage>
    with SingleTickerProviderStateMixin {
  AnimationController animationController;
  Animation animation;

  @override
  void initState() {
    super.initState();
    animationController = AnimationController(
      duration: Duration(
        seconds: 2,
      ),
      vsync: this,
    );
    animation = CurvedAnimation(
      parent: animationController,
      curve: Curves.fastOutSlowIn,
    );
    animationController.addStatusListener(animationStatusListener);
    animationController.forward();
  }

  void animationStatusListener(AnimationStatus status) {
    if (status == AnimationStatus.completed) {
      animationController.reverse();
    } else if (status == AnimationStatus.dismissed) {
      animationController.forward();
    }
  }

  Widget _buildCircle(radius) {
    return Container(
      width: radius * 2,
      height: radius * 2,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.all(
          Radius.circular(radius),
        ),
        color: Colors.red,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Rotating Circle"),
      ),
      body: Align(
        alignment: Alignment(0, -0.1),
        child: AnimatedBuilder(
          child: _buildCircle(30.0),
          animation: animationController,
          builder: (BuildContext context, Widget child) {
            return Transform.rotate(
              child: child,
              angle: math.pi * 2 * animation.value,
              origin: Offset(0, 30),
            );
          },
        ),
      ),
    );
  }
}

讓我解釋一下上面代碼的重要部分合呐。

animation = CurvedAnimation(
  parent: animationController,
  curve: Curves.fastOutSlowIn,
);

默認(rèn)情況下,AnimationController在給定的持續(xù)時(shí)間內(nèi)線性生成從0.0到1.0的數(shù)字笙以,因此動畫無任何速度播放淌实。如果我們想要改變動畫的速度和樣式,我們可以將它包裝在CurvedAnimation小部件中:

當(dāng)您想要將非線性曲線應(yīng)用于動畫對象時(shí),CurvedAnimation非常有用拆祈,特別是當(dāng)您想要動畫前進(jìn)時(shí)的曲線與后退時(shí)的曲線時(shí)恨闪。

請注意,可以首先在CurvedAnimation小部件中包裝動畫放坏,然后使用Tween小部件轉(zhuǎn)換其下限和上限咙咽,如下所示:

animation = Tween(begin: 5.0, end: 10.0).animate(
  CurvedAnimation(
    parent: animationController,
    curve: Curves.fastOutSlowIn,
  ),
);

在這里,我使用了曲線淤年。fastOutSlowIn曲線钧敞,但您可以使用其他值并查看它們?nèi)绾斡绊憚赢嫷乃俣群退俣取?/p>

現(xiàn)在讓我解釋一下構(gòu)建方法:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text("Rotating Circle"),
    ),
    body: Align(
      alignment: Alignment(0, -0.1),
      child: AnimatedBuilder(
        child: _buildCircle(30.0),
        animation: animationController,
        builder: (BuildContext context, Widget child) {
          return Transform.rotate(
            child: child,
            angle: math.pi * 2 * animation.value,
            origin: Offset(0, 30),
          );
        },
      ),
    ),
  );
}

我們已將該child屬性設(shè)置AnimatedBuilder為圓圈。為什么麸粮?因?yàn)槲覀兿M粍?chuàng)建一次溉苛,而不是每一幀!(為了提高性能弄诲,我們不需要重建不隨時(shí)間變化的動畫部分炊昆。這里我們的圓圈大小在動畫期間保持不變,所以我們只構(gòu)建它一次并將它分配給孩子AnimatedBuilder威根。builder每次繪制新幀時(shí),該子項(xiàng)都可以在方法中重復(fù)使用视乐。

builder我們動畫的每一幀都會調(diào)用的方法中洛搀,我們習(xí)慣Transform.rotate了旋轉(zhuǎn)圓圈。如果我們不指定origin參數(shù)佑淀,圓圈將圍繞其自身的中心旋轉(zhuǎn)(在這種情況下留美,由于圓圈圍繞其自身的中心旋轉(zhuǎn),我們將看不到任何旋轉(zhuǎn)I烊小)谎砾。出于這個(gè)原因,我們將旋轉(zhuǎn)中心設(shè)置為偏移(0,30)表示的點(diǎn)捧颅,該點(diǎn)是距離窗口小部件中心的x距離為0景图,y距離為30的點(diǎn)。請查看以下內(nèi)容圖片碉哑。圓圈現(xiàn)在將圍繞標(biāo)有X的原點(diǎn)旋轉(zhuǎn):

旋轉(zhuǎn)角度已設(shè)置為:

angle: math.pi * 2 * animation.value,

由于動畫值從0變?yōu)?挚币,旋轉(zhuǎn)角度將從0變?yōu)?strong>2π,這等于完整的360°旋轉(zhuǎn)扣典。

重要說明:我沒有包含_buildCircle(30.0)在Align小部件中妆毕。相反,我已經(jīng)在Align小部件中包裝了整個(gè)動畫贮尖,這是我們的AnimatedWidget對象笛粘。那是因?yàn)槲覀冎幌胄D(zhuǎn)圓圈,而不是旋轉(zhuǎn)它周圍的空間!如果我們在Align小部件中包裝了AnimatedBuilder的子節(jié)點(diǎn)薪前,那么我們的圓圈周圍會有一個(gè)額外的空間润努,這會導(dǎo)致我們的計(jì)算出錯(cuò)。我的全部觀點(diǎn)是以下代碼是錯(cuò)誤的:

animated_circle_page.dart

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Rotating Circle"),
      ),
      body: AnimatedBuilder(
        child: Align(
          alignment: Alignment(0, -0.1),
          child: _buildCircle(30.0),
        ),
        animation: animationController,
        builder: (BuildContext context, Widget child) {
          return Transform.rotate(
            child: child,
            angle: math.pi * 2 * animation.value,
            origin: Offset(0, 30),
          );
        },
      ),
    );
  }

與上一個(gè)動畫一樣序六,當(dāng)動畫完成時(shí)任连,我們將其反轉(zhuǎn),使其從2π旋轉(zhuǎn)回0 度例诀。結(jié)果是以下動畫:

圓周圍原點(diǎn)旋轉(zhuǎn)

在上一篇文章中随抠,我們學(xué)習(xí)了如何繪制彎曲的虛線。我告訴過你關(guān)于創(chuàng)建以下動畫的信息:

我將在github上的本文代碼中包含上述動畫的源代碼繁涂。但我建議你自己創(chuàng)作作為家庭作業(yè)拱她!請注意,我沒有在彎曲的路徑上移動碟子扔罪。我正在使用Transform.translate小部件在兩條獨(dú)立的直線上設(shè)置動畫秉沼。Transform.translate可用于在繪制對象之前dxdy之前偏移對象。

摘要矿酵,回顧和最終說明

而已唬复。你可以在這里停止閱讀!我只想強(qiáng)調(diào)以下注釋全肮,我從Flutter提供的關(guān)于動畫的三篇文章中抓取了這些文章(閱讀這些文章很好):

  1. 動畫概述
  2. 動畫教程
  3. 動畫簡介

要創(chuàng)建動畫敞咧,首先要創(chuàng)建一個(gè)AnimationController。除了作為動畫本身辜腺,還AnimationController可以控制動畫休建。例如,您可以告訴控制器向前播放動畫或停止動畫评疗。

AnimationController是一個(gè)特殊Animation對象测砂,只要硬件準(zhǔn)備好新幀,它就會生成一個(gè)新值百匆。默認(rèn)情況下砌些,AnimationController在給定的持續(xù)時(shí)間內(nèi)線性生成從0.0到1.0的數(shù)字。

AnimationController派生自Animation<double>加匈,因此它可以在需要Animation對象的任何地方使用寄症。但是,AnimationController還有其他控制動畫的方法矩动。例如有巧,您使用該.forward()方法啟動動畫。數(shù)字的生成與屏幕刷新有關(guān)悲没,因此通常每秒生成60個(gè)數(shù)字篮迎。

的[Tween(https://api.flutter.dev/flutter/animation/Tween-class.html)抽象類中的類型值的范圍0.0-1.0映射名義上的雙精度值(例如Color男图,或另一種雙)。這是一個(gè)Animatable甜橱。要設(shè)置超過0.0到1.0間隔的動畫逊笆,可以使用a [Tween<T>](https://api.flutter.dev/flutter/animation/Tween-class.html),它在其開始值和結(jié)束值之間進(jìn)行插值岂傲。許多類型都有特定的Tween子類难裆,它們提供特定于類型的插值。例如镊掖,ColorTween在顏色之間插值乃戈,RectTween在矩形之間插值。A Tween繼承自Animatable<T>而非繼承Animation<T>亩进。像動畫一樣的Animatable不必輸出double症虑。例如,ColorTween指定兩種顏色之間的進(jìn)展:

colorTween = ColorTween(begin: Colors.transparent, end: Colors.black54);

可以在Github上找到本文的源代碼归薛。

動畫菜的源代碼可以在這里找到谍憔。

謝謝閱讀!

轉(zhuǎn):https://medium.com/@meysam.mahfouzi/understanding-animations-in-flutter-b8ec789d94a4

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末主籍,一起剝皮案震驚了整個(gè)濱河市习贫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌千元,老刑警劉巖苫昌,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異诅炉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)屋厘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門涕烧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人汗洒,你說我怎么就攤上這事议纯。” “怎么了溢谤?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵瞻凤,是天一觀的道長。 經(jīng)常有香客問我世杀,道長阀参,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任瞻坝,我火速辦了婚禮蛛壳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己衙荐,他們只是感情好捞挥,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著忧吟,像睡著了一般砌函。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上溜族,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天讹俊,我揣著相機(jī)與錄音,去河邊找鬼斩祭。 笑死劣像,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的摧玫。 我是一名探鬼主播耳奕,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼诬像!你這毒婦竟也來了屋群?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤坏挠,失蹤者是張志新(化名)和其女友劉穎芍躏,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體降狠,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡对竣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了榜配。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片否纬。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蛋褥,靈堂內(nèi)的尸體忽然破棺而出临燃,到底是詐尸還是另有隱情,我是刑警寧澤烙心,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布膜廊,位于F島的核電站,受9級特大地震影響淫茵,放射性物質(zhì)發(fā)生泄漏爪瓜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一匙瘪、第九天 我趴在偏房一處隱蔽的房頂上張望钥勋。 院中可真熱鬧炬转,春花似錦、人聲如沸算灸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽菲驴。三九已至荐吵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赊瞬,已是汗流浹背先煎。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留巧涧,地道東北人薯蝎。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像谤绳,于是被迫代替她去往敵國和親占锯。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 該文已授權(quán)公眾號 「碼個(gè)蛋」缩筛,轉(zhuǎn)載請指明出處 在 Flutter 中消略,自帶手勢監(jiān)聽的目前為止好像只有按鈕部件和一些...
    Kuky_xs閱讀 1,691評論 2 3
  • 本文通過代碼層面去分析Flutter動畫的實(shí)現(xiàn)過程,介紹了Flutter中的Animation庫以及Physics...
    Q吹個(gè)大氣球Q閱讀 3,446評論 2 12
  • 在Flutter應(yīng)用程序中實(shí)現(xiàn)超級流暢的動畫 在這篇文章中瞎抛,我將帶您完成在Flutter應(yīng)用程序中實(shí)現(xiàn)流暢動畫的步...
    開心人開發(fā)世界閱讀 28,315評論 14 167
  • 1 背景 不能只分析源碼呀艺演,分析的同時(shí)也要整理歸納基礎(chǔ)知識,剛好有人微博私信讓全面說說Android的動畫桐臊,所以今...
    未聞椛洺閱讀 2,691評論 0 10
  • 1 第一次嘗試跟自己的身體進(jìn)行對話断凶,是在讀德芬姐姐的《遇見未知的自己》的時(shí)候伤提,無意中遇見這本書,沒想到能夠帶給自己...
    柒月柒閱讀 635評論 0 0