[React Native]動(dòng)畫-LayoutAnimation

實(shí)現(xiàn)動(dòng)畫的幾種方式:

  • requestAnimationFrame
  • setNativeProps
  • LayoutAnimation
  • Animated

本篇文章我們會(huì)介紹前三種方式漓拾,以及它們的區(qū)別骇两。下一篇文章會(huì)介紹高級(jí)API—Animated的用法。

requestAnimationFrame
如果不使用任何動(dòng)畫API配阵,我會(huì)想到一種簡單粗暴的方式來實(shí)現(xiàn)動(dòng)畫效果—通過修改state不斷改變視圖的樣式棋傍。

我們來個(gè)簡單的示例:

class Demo9 extends Component {
  constructor(props) {
      super(props);
      this.state = {
          width: 100,
          height: 100
      };
  }
  startAnimation() {
      var count = 0;
      while (++count < 50) {
          requestAnimationFrame(() = >{
              this.setState({
                  width: this.state.width + 1,
                  height: this.state.height + 1
              });
          });
      }
  }
  render() {
      return ( 
         <View style = {styles.container}> 
           <Image source = { require('./icon.jpg') }
              style={{width: this.state.width, height: this.state.height}}/>
           <TouchableOpacity style={styles.instructions} onPress={()=>this.startAnimation()}>
              <Text style={{alignSelf: 'center', color: '#FFFFFF'}}>Press me!</Text> 
           </TouchableOpacity>
          </View> 
      );
  }
}

效果圖如下:

preview1.gif

這個(gè)方式實(shí)現(xiàn)的動(dòng)畫有幾個(gè)問題:
1瘫拣、實(shí)現(xiàn)方式是通過不斷銷毀麸拄、創(chuàng)建視圖來完成,一方面如果你的視圖的數(shù)據(jù)是動(dòng)態(tài)獲取的,那么就需要以合適的方式恢復(fù)數(shù)據(jù)失球;另外一方面实苞,這種方式必然造成性能和內(nèi)存開銷的問題烈疚。
2爷肝、如果需要刷新的View的層級(jí)比較深,那么這種方式會(huì)帶來嚴(yán)重的性能問題金赦。
3夹抗、requestAnimationFrame畢竟是webcss的用法纵竖,在手機(jī)上靡砌,動(dòng)畫的效果比較生硬通殃,如果需要‘彈性動(dòng)畫’,‘淡入淡出’等效果恨诱,則是比較難以實(shí)現(xiàn)的(需要輔助各種函數(shù))照宝。

setNativeProps
如果執(zhí)意使用修改state的方式句葵,覺得這種方式更符合當(dāng)前需求對(duì)動(dòng)畫的控制,那么則應(yīng)當(dāng)使用原生組件的setNativeProps方法來做對(duì)應(yīng)實(shí)現(xiàn)把将,它會(huì)直接修改組件底層特性忆矛,不會(huì)重繪組件催训,因此性能也遠(yuǎn)勝動(dòng)態(tài)修改組件內(nèi)聯(lián)style的方法。

我們稍微修改下startAnimation方法:

startAnimation() {
  var count = 0;
  while (++count < 50) {
      requestAnimationFrame(() = >{
          this.refs.image.setNativeProps({
              style: {
                  width: this.state.width++,
                  height: this.state.height++
              }
          });
      });
  }
}

其中this.refs.image指向的是Image視圖亚兄,效果圖如下(比上一種方式流暢多了~):

preview2.gif

優(yōu)點(diǎn):
setNativeProps直接修改組件底層特性,不會(huì)重繪組件礼旅,因此性能也遠(yuǎn)勝動(dòng)態(tài)修改組件內(nèi)聯(lián)style的方法各淀。
缺點(diǎn):
1碎浇、setNativeProps屬于原生視圖的方法,如果我們使用一個(gè)動(dòng)畫泉唁,單純只是為了跟蹤它的值弄跌,那么這么方法有點(diǎn)不合時(shí)宜。
2跟磨、還是和上面一種方式一樣,如果需要實(shí)現(xiàn)‘彈性動(dòng)畫’攒盈,‘淡入淡出’等效果抵拘,則還是比較麻煩的。


重點(diǎn)型豁,本篇文章的主角要登場了(此處有掌聲~)

LayoutAnimation
當(dāng)布局變化時(shí)僵蛛,自動(dòng)將視圖運(yùn)動(dòng)到它們新的位置上尚蝌。
一個(gè)常用的調(diào)用此API的辦法是調(diào)用LayoutAnimation.configureNext(config),然后調(diào)用setState充尉。

建議大家閱讀的時(shí)候打開LayoutAnimation源碼飘言,路徑為:
xxx/node_modules/react-native/Libraries/LayoutAnimation/LayoutAnimation.js驼侠,其中‘xxx’為當(dāng)前項(xiàng)目文件夾姿鸿。

一個(gè)標(biāo)準(zhǔn)的config格式如下:(createupdatedelete泪电,分別表示視圖創(chuàng)建般妙、更新刪除時(shí)候的動(dòng)畫)

Config.png

示例:

{   
  duration: 700,   //持續(xù)時(shí)間   
  create: {   // 視圖創(chuàng)建         
    type: LayoutAnimation.Types.linear,      
    property: LayoutAnimation.Properties.scaleXY // opacity纪铺、scaleXY   
  },   
  update: { // 視圖更新      
    type: LayoutAnimation.Types.spring,      
    springDamping: 0.4   
  },
}

其中create相速、updatedeleteAnim格式如下:

Anim.png

delay:延遲指定時(shí)間(單位:毫秒)
springDamping:彈跳動(dòng)畫阻尼系數(shù)(配合spring使用)
initialVelocity:初始速度
type:類型定義在LayoutAnimation.Types中:

  • spring:彈跳
  • linear:線性
  • easeInEaseOut:緩入緩出
  • easeIn:緩入
  • easeOut:緩出

property:類型定義在LayoutAnimation.Properties中:

  • opacity:透明度
  • scaleXY:縮放

讓我們來看一段示例代碼,同樣是修改startAnimation方法:

startAnimation() {
  LayoutAnimation.configureNext({
    duration: 700, //持續(xù)時(shí)間
    create: { // 視圖創(chuàng)建
        type: LayoutAnimation.Types.spring,
        property: LayoutAnimation.Properties.scaleXY,// opacity鲜锚、scaleXY
    },
    update: { // 視圖更新
        type: LayoutAnimation.Types.spring,
    },
  });
  this.setState({width: this.state.width + 10, height: this.state.height + 10});
}

效果圖如下:


config1.gif

觀察下這個(gè)動(dòng)畫:
視圖創(chuàng)建的時(shí)候是縮放動(dòng)畫突诬,點(diǎn)擊‘Press Me!’,圖片也會(huì)有個(gè)縮放動(dòng)畫芜繁。

我們還可以通過LayoutAnimation.create這個(gè)函數(shù)更簡單的創(chuàng)建一個(gè)config旺隙,同樣可以實(shí)現(xiàn)和上圖一樣的效果。

startAnimation() {
  LayoutAnimation.configureNext(LayoutAnimation.create(700, 
             LayoutAnimation.Types.spring, 
             LayoutAnimation.Properties.scaleXY));
  this.setState({width: this.state.width + 10, height: this.state.height + 10});
}

create函數(shù)接受三個(gè)參數(shù):

  • duration:動(dòng)畫持續(xù)時(shí)間骏令。
  • type:createupdate時(shí)的動(dòng)畫類型蔬捷,定義在* LayoutAnimation.Types
  • creationProp:create時(shí)的動(dòng)畫屬性榔袋,定義在LayoutAnimation.Properties周拐。

create的源碼:

create.png

效果圖和上圖一樣,這里不在貼出來了凰兑。

實(shí)際上妥粟,系統(tǒng)已經(jīng)為我們提供了3個(gè)默認(rèn)的動(dòng)畫,定義在LayoutAnimation.Presets中:

  • easeInEaseOut:緩入緩出
  • linear:線性
  • spring:彈性

一個(gè)簡單的示例:

startAnimation() {
  LayoutAnimation.configureNext(LayoutAnimation.Presets.linear);
  this.setState({width: this.state.width + 10, height: this.state.height + 10});
}

具體參數(shù)配置吏够,請(qǐng)查看Presets源碼:

Presets.png

我們來分析下LayoutAnimation的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):
1勾给、效果非常的流暢,而且動(dòng)畫的過程很柔和锅知,絲毫沒有生硬的感覺播急。
2、可以靈活的配置動(dòng)畫參數(shù)售睹,基本能滿足單個(gè)動(dòng)畫的需求旅择。
缺點(diǎn):
1、如果要實(shí)現(xiàn)‘組合順序’動(dòng)畫侣姆,比如先縮小50%生真、再向左平移100像素沉噩,那么就比較麻煩了,需要監(jiān)聽上一個(gè)動(dòng)畫的結(jié)束事件柱蟀,再進(jìn)行下一個(gè)川蒙。那么問題來了,configureNext第二個(gè)參數(shù)是可以監(jiān)聽動(dòng)畫結(jié)束的长已,但是只在IOS平臺(tái)有效畜眨!
2、如果動(dòng)畫的效果更為復(fù)雜术瓮,比如同時(shí)執(zhí)行動(dòng)畫康聂,再順序執(zhí)行,對(duì)于編程來講胞四,需要做的事情很多恬汁,復(fù)雜度也大大提升。

那么如何定制更靈活豐富的動(dòng)畫效果呢辜伟,這就需要使用到高級(jí)動(dòng)畫API Animated氓侧。下一篇文章我們會(huì)介紹高級(jí)動(dòng)畫API—Animated的使用,感興趣的朋友請(qǐng)繼續(xù)閱讀[React Native]動(dòng)畫-Animated导狡。

本文的源碼地址Demo9

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末约巷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子旱捧,更是在濱河造成了極大的恐慌独郎,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枚赡,死亡現(xiàn)場離奇詭異氓癌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)标锄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門顽铸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人料皇,你說我怎么就攤上這事谓松。” “怎么了践剂?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵鬼譬,是天一觀的道長。 經(jīng)常有香客問我逊脯,道長优质,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮巩螃,結(jié)果婚禮上演怎,老公的妹妹穿的比我還像新娘。我一直安慰自己避乏,他們只是感情好爷耀,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拍皮,像睡著了一般歹叮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上铆帽,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天咆耿,我揣著相機(jī)與錄音,去河邊找鬼爹橱。 笑死萨螺,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宅荤。 我是一名探鬼主播屑迂,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼浸策,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼冯键!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起庸汗,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤惫确,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蚯舱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體改化,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年枉昏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了陈肛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡兄裂,死狀恐怖句旱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晰奖,我是刑警寧澤谈撒,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站匾南,受9級(jí)特大地震影響啃匿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一溯乒、第九天 我趴在偏房一處隱蔽的房頂上張望夹厌。 院中可真熱鬧,春花似錦裆悄、人聲如沸尊流。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽崖技。三九已至,卻和暖如春钟哥,著一層夾襖步出監(jiān)牢的瞬間迎献,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工腻贰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吁恍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓播演,卻偏偏與公主長得像冀瓦,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子写烤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫翼闽、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,033評(píng)論 4 62
  • React Native 進(jìn)階(二)--動(dòng)畫 動(dòng)畫 流暢洲炊、有意義的動(dòng)畫對(duì)于移動(dòng)應(yīng)用用戶體驗(yàn)來說是非常必要的感局。我們可...
    呼呼哥閱讀 2,749評(píng)論 2 5
  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點(diǎn)贊按鈕進(jìn)度條TabLayout圖標(biāo)下拉刷新...
    皇小弟閱讀 46,712評(píng)論 22 664
  • 許是在家和高中同桌、初中同桌碰面太嗨了暂衡,忘了盯孩子的作業(yè)询微;許是走那天的叮嚀太多,讓孩子爸有些不耐煩狂巢,我也就及時(shí)打住...
    知書家庭閱讀 233評(píng)論 0 0
  • 曾經(jīng)各種小打小鬧的抑郁撑毛,在這畢業(yè)半年來,總于迫不及待的爆發(fā)開來唧领。封閉自己藻雌,暗無天日,沒有色彩疹吃,可以回避蹦疑,可以假裝,...
    Maxdiane閱讀 215評(píng)論 0 0