ART是React Naive下的繪圖框架哮奇。
Android項(xiàng)目默認(rèn)就包含ART庫承二,而iOS需要單獨(dú)添加依賴庫诞丽。
方式一:
1.右鍵點(diǎn)擊項(xiàng)目 -> ‘Add Files to ProjectName -> 選擇 node_modules/react-native/React/Libraries/ART/ART.xcodeproj’
2.將 libART.a 添加到 Linked Frameworks and Libraries型将。
方式二:
cocoapods方式引入:
pod 'React-ART', :path => '../node_modules/react-native/Libraries/ART'
ART具體使用:官方文檔
如果是自己通過ART寫的自定義組件够挂,而又希望能在該組件下編寫動(dòng)畫钞速〈矗可以參考以下解決方案。
1.Animated具體使用: 官方文檔
通過文檔我們可以了解到渴语,Animated默認(rèn)所支持View類型只有:
Animated.Image
Animated.ScrollView
Animated.Text
Animated.View
這四種類型苹威。所以,如果想要通過ART繪制的自定義View驾凶,我們需要借助
Animated.createAnimatedComponent()
接下來牙甫,我們通過ART繪制的圓圈,來配合Animted 實(shí)現(xiàn)一個(gè)簡單的動(dòng)畫调违。
- 導(dǎo)入文件窟哺。(Circle是自定義繪制的圓圈組件)
import { Easing ,Animated} from 'react-native';
import Circle from './Circle'
- 處理Circle組件,讓其具備有做動(dòng)畫的能力技肩。
const AnimatedProgres = Animated.createAnimatedComponent(Circle);
3.定義動(dòng)畫value屬性且轨。
constructor(props) {
super(props);
this.state = {
fillAnimation: new Animated.Value(props.preValue),
};
}
4.設(shè)值。
render() {
return <AnimatedProgres progress={this.state.fillAnimation} />;
}
5.執(zhí)行動(dòng)畫虚婿。
componentDidMount() {
this.animate();
}
animate(toVal, dur, ease) {
const toValue = toVal >= 0 ? toVal : this.props.progress;
const duration = dur || this.props.duration;
const easing = ease || this.props.easing;
const anim = Animated.timing(this.state.fillAnimation, {
toValue,
easing,
duration,
});
anim.start(this.props.animatedCompelte);
return anim;
}
具體代碼可以查看我的Demo:https://github.com/AutoJiang/animated-circle-progress
接下來旋奢,我們來了解一下,這個(gè)動(dòng)態(tài)遞增的Text動(dòng)畫是怎么做的雳锋。
剛開始黄绩,我想了一個(gè)比較粗糙的方法。
直接設(shè)置一個(gè)定時(shí)器玷过,每隔0.01秒重復(fù)去更新值爽丹,然后刷新頁面筑煮。
代碼如下:
state = {
count: 0,
}
countBegin(){
setInterval(()=>{
if(this.state.count != this.props.progress * 100){
this.state.count++;
this.setState({});
}
},10)
}
componentDidMount(){
this.countBegin()
}
render(){
const {fontSize,progress,...other} = this.props;
let progress1 = this.props.progress >= 1 ? 0.9999: this.props.progress;
return <AnimatedCircle
{...other}
progress = {progress1}
>
<Text style = {{color:'#2C6FB7',fontSize: fontSize, textAlign:'right'}}>{this.state.count}
<Text style = {{color:'#2C6FB7',fontSize: fontSize - 2}}>%</Text>
</Text>
</AnimatedCircle>;
}
通過上面的GIF動(dòng)畫可以觀察到兩個(gè)明顯的問題。
- 兩個(gè)動(dòng)畫是獨(dú)立的粤蝎,圓圈動(dòng)畫已經(jīng)結(jié)束了真仲,但是數(shù)字遞增動(dòng)畫還沒有。
- 數(shù)字遞增動(dòng)畫不連貫初澎,有明顯的卡頓現(xiàn)象秸应。
仔細(xì)琢磨一下也能夠知道為什么,原因在于setState()調(diào)用得太頻繁了碑宴,render函數(shù)不斷的被調(diào)用软啼,這是非常消耗性能的事情,再加上setInterval本身就不是一個(gè)很精準(zhǔn)的定時(shí)器延柠,所以這種方案本質(zhì)上就是行不通的祸挪。
那么應(yīng)該如何優(yōu)雅的解決這個(gè)問題呢?
我通過觀察官方文檔得到了靈感:
既然Animated的設(shè)計(jì)緣由就是為了防止react重新渲染和重新調(diào)和的開銷贞间,那么我們?yōu)楹尾焕^續(xù)以Animated的方式去做這個(gè)數(shù)字遞增的動(dòng)畫呢贿条?
接下來,我只增加了一句代碼增热。
在Circle.js的正中間整以,增加了一個(gè)基于progress字段的Text。
<View style = {{position: 'absolute',left: 0, top: 0, right: 0, bottom: 0,alignItems:'center',justifyContent:'center'}}>
<Text> {Math.round(progress*100)}%</Text>
</View>
由于圓圈progress的動(dòng)畫已經(jīng)是做好的峻仇,所以我們利用這個(gè)字段寫好代碼公黑,也能做出其他動(dòng)畫效果。
另附demo源碼