废话在前
记得之前很多App在引导界面和登录使用视频,最近好像很多App登录界面开始使用无限循环滚动的看似长图的背景页了。
这不,最近App又改版了,有一个需求就是把登录背景改成可以无限滚动的,页面背景是很多个男女头像组合。想必这种很多人都见过了,反正我是见过了😌。 用过小红书的同学应该比较熟悉,由于一直不知道小红书是干啥的,之前在测试机上无意中看到小红书的app,就点开了,发现他们登录界面的背景就是无限滚动的,只不过人家的背景是人物食物景色都有。当时还问了同事有么有想过这个咋实现的,当时猜测是视频或者GIF图。当然视频肯定是可以的,只要衔接的好。 GIF好像会闪,优化的好应该也问题不大。
但是这种成本就有点大了,加上我们这种“代码驱动型”的,一切能用代码的就得用代码实现,你懂的。
说下思路历程:起先就是在纸上画画画,发现大概这样。就开始写。
由于项目是RN开发,这边就是用了Animated.Image做个动画,纸上画的估计没人知道是啥😁,我先用一个能不能行呢(肯定是不行的),先看看效果。看完效果晓得了,再加一个,666,成了
。
什么思路呢?这里其实就是一个障眼法,就是一个屏幕放两张图片,一个在屏幕内一个在屏幕外,当第一张完全滚动出屏幕的时候,第二张正好完全进去屏幕,这个时候就让第一张回到初始位置,第二张也回到初始位置,重新进行之前的动画。
效果
播放
小红书效果
播放
RN效果
播放
原生效果
React Native实现
布局如下
1 <View style={{ flex: 1, backgroundColor: 'black' }}> 2 <Animated.Image source={{ uri: 'ic_login_bg' }} style={{ 3 width: device.width, height: device.height, 4 transform: [{ 5 translateY: this.animTranslateY.interpolate({ 6 inputRange: [0, 1], 7 outputRange: [0, 0 - device.height] 8 }) 9 }]10 }} />11 <Animated.Image source={{ uri: 'ic_login_bg' }} style={{12 width: device.width, height: device.height,13 transform: [{14 translateY: this.animTranslateY2.interpolate({15 inputRange: [0, 1],16 outputRange: [0, 0 - device.height]17 })18 }]19 }} />20 </View>21
开启动画和暂停动画
1 startTranslateAnim() { 2 Animated.parallel([ 3 Animated.timing( 4 this.animTranslateY, { 5 toValue: 1, 6 duration: 50000, 7 useNativeDriver: true, 8 easing: Easing.linear 9 }10 ),11 Animated.timing(12 this.animTranslateY2, {13 toValue: 1,14 duration: 50000,15 easing: Easing.linear,16 useNativeDriver: true,17 }18 )19 ]).start(() => {20 this.animTranslateY.setValue(0)21 this.animTranslateY2.setValue(0)22 if (!this.state.animStop) {23 this.startTranslateAnim()24 }25 })26 }27 stopTranslateAnim() {28 this.setState({29 animStop: true30 })31 Animated.timing(this.animTranslateY).stop(),32 Animated.timing(this.animTranslateY2).stop()33 }3435 componentDidMount() {36 //开始动画37 this.startTranslateAnim();38 }39 componentWillMount() {40 //暂停动画41 this.stopTranslateAnim();42 }
原生实现
既然有了思路,那么原生也是一样的,废话不多说,直接贴代码
1/** 2 * Created by Kevin on 2019-12-16<br/> 3 * Blog:http://student9128.top/ 4 * 公众号:竺小竹 5 * Describe:<br/>无限滚动背景页 6 */ 7class AnimBGActivity : AppCompatActivity() { 8 override fun onCreate(savedInstanceState: Bundle?) { 9 super.onCreate(savedInstanceState)10 window.setFlags(11 WindowManager.LayoutParams.FLAG_FULLSCREEN,12 WindowManager.LayoutParams.FLAG_FULLSCREEN13 )14 setContentView(R.layout.activity_anim_bg)15 val displayMetrics = DisplayMetrics()16 windowManager.defaultDisplay.getMetrics(displayMetrics)17 val widthPixels = displayMetrics.widthPixels18 val heightPixels = displayMetrics.heightPixels19 var llContainer: LinearLayout = findViewById(R.id.ll_container)20 var imageV = ImageView(this)21 var imageVV = ImageView(this)22 val layoutParams = LinearLayout.LayoutParams(widthPixels, heightPixels)23 imageV.layoutParams = layoutParams24 imageVV.layoutParams = layoutParams25 imageV.setImageResource(R.drawable.ic_login)26 imageVV.setImageResource(R.drawable.ic_login)27 imageV.scaleType=ImageView.ScaleType.CENTER_CROP28 imageVV.scaleType=ImageView.ScaleType.CENTER_CROP29 llContainer.addView(imageV)30 llContainer.addView(imageVV)31 showAnim(imageV, heightPixels)32 showAnim(imageVV, heightPixels)33 }34 private fun showAnim(image: ImageView, heightPixels: Int) {35 val animator =36 ObjectAnimator.ofFloat(image, "translationY", 0f, (0 - heightPixels).toFloat())37 animator.duration = 500038 animator.interpolator = LinearInterpolator()39 animator.repeatCount = Animation.INFINITE40 animator.start()41 }42}
欢迎读者朋友分享 竺小竹公众号给你身边的朋友😋,欢迎爱写文章的朋友踊跃投稿~🙏