對於一些既定的界面元素,圖片、文字、滾動視圖等動畫效果,咱們會優先選擇 Animated 來進行處理。可是若是你的動畫效果須要改變佈局,涉及到其餘的 View 或者節點元素。那麼就應該優先考慮 LayoutAnimation 來實現了。spring
較之於 Animated,LayoutAnimation 的使用要更簡單。 若是你用 state 記錄並改變過某一 View 的高度,那麼在此基礎上只須要調用一下LayoutAnimation 的動畫函數,並保證父節點是 flex 佈局的,就能夠實現這一高度變化的動畫。函數
注意:在Android 上使用 LayoutAnimation 須要導入 UIManager 並啓用:工具
UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);佈局
[動畫1 - 改變佈局高度,將同級 View 往下推]性能
效果:flex
實現:動畫
UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
export default class LayoutAnimated extends Component {
state = {
moreHeight: 0, //動態高度
};
_onPress = () => {
LayoutAnimation.spring(); //調用 LayoutAnimation 動畫
this.setState({moreHeight: this.state.moreHeight === 0 ? 100 : 0})
}
render() {
return (
<View style={{flex: 1, paddingHorizontal: 20}}>
<View style={styles.card_view}>
<TouchableOpacity onPress={this._onPress}> // 爲看到點擊效果,不在 Text中實現 onPress
<Text style={styles.more_text}>查看更多</Text>
</TouchableOpacity>
<View style={{height: this.state.moreHeight}}/> //變量直接設定給 View
</View>
<View style={{backgroundColor: '#e29fae', height: 100}}/>
</View>
);
}
}
const styles = StyleSheet.create({
card_view: {backgroundColor: '#ebde5d', marginTop: 20},
more_text: {textAlign: 'right', paddingVertical: 8, borderBottomColor: '#ccc', borderBottomWidth: 1},
});
複製代碼
可見,外部佈局是彈性佈局的時候,在 setState 的基礎上調用一次 LayoutAnimation.spring() ,就能夠實現佈局改變的動畫。this
若是使用的動畫,須要頻繁地刷新,進行 setState,就一定會影響到性能。 此時能夠嘗試使用 setNativeProps 來進行修改 ,該方法直接修改基於原生視圖的組件的屬性來達到效果。spa
這種直接操做組件的操做並非應該常常使用的工具。 通常只是用來建立連續的動畫,同時避免渲染組件結構和同步太多視圖變化所帶來的大量開銷。 setNativeProps 是一個「簡單粗暴」的方法,它直接在底層(DOM、UIView 等)而不是 Rea ct 組件中記錄 state,這樣會使代碼邏輯難以理清。因此在使用這個方法以前,請儘可能先嚐試用 setState 和 shouldComponentUpdate 方法來解決問題。 (引用自官方文檔)code
因此, setNativeProps 是一個強大但也是不得已而爲之的選擇。
[動畫2 - setNativeProps 實現頭部欄透明度漸變 ]
有時咱們會須要在列表視圖滾動的時候,頭部欄有一個透明度漸變的效果。在滑動到必定的距離以後,頭部欄再也不透明。
通常思路是這樣,重寫 ScrollView 的 onScroll 方法,判斷當前所處的 y 值,並經過當前 y 值所處範圍計算出應該設置的透明度。可是若是此時用 state 記錄透明度,setState 完成設置刷新的話,開銷的巨大的,甚至致使必定的卡頓 [onScroll 的觸發十分頻繁 (scrollEventThro 能夠改變 onScroll 調用頻率但不推薦)]。因此這裏咱們應該選擇的是 setNativeProps。
實現:
<View //頭部view ,設定 ref
ref={head => this.headerView = head}
...
</View>
複製代碼
在滑動的 y 值在(50,100] 之間的時候,設置透明度爲 y/100 。這樣在 50 如下都是 0.5 半透明, 100 日後透明度都是 1,即不透明。
//ScrollView 的 onScroll 方法
onScroll = ({nativeEvent, contentOffset}) => {
// console.info('nativeEvent', nativeEvent);
const currentY = nativeEvent.contentOffset.y;
if (currentY > 50 && currentY <= 100) {
this.headerView.setNativeProps({
style: {opacity: currentY / 100}
})
}
}
複製代碼
能夠看到,setNativeProps 在這個場景中仍是很是適用的,若是你體驗過 setState,就能很明顯的感覺到它的優點了。