这种动态背景页面你遇到过吗?

387 阅读8分钟

废话在前

记得之前很多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}

欢迎读者朋友分享 竺小竹公众号给你身边的朋友😋,欢迎爱写文章的朋友踊跃投稿~🙏