ReactNative 吸顶

效果图片

感谢同事提供的店铺UI图和思路。
图录的不太好,但意思差不多表明了。

其实如果结构不复杂的话,可以使用SectionList实现,但我这用的是ScrollTabView,ScrollTabView里面还有列表组件,嵌套在SectionList中很麻烦。。。对 我试过了。。。

最开始我的思路是:
滚动组件包括ScrollView,ListView,FlatList,SectionList,这里统一写成ScrollView,具体代码几乎无差别。
ScrollView滚动的时候监听它,上滑多少距离,就把头部那个苹果旗舰店的(或者其他你需要顶上去的东西)的高度相应减去多少,直至变成0,那么自然就达到了吸顶的效果,但是弊端是ScrollView的高度是一直在变化的,iOS上没有问题,但是在android上,因为ScrollView在滚动,同时高度在不停变化会疯狂的抖动,抖的根本没法用,所以有了下个思路,本例也是下个思路完成的.

新思路:同样是要监听滚动事件,但是不改变ScrollView的高度,我们把头部使用绝对布局定位到上方,下面的用相对布局直接接上去就好了。默认下方的ScrollTabView的marginTop:0,滚动的时候,上方头部的top不断缩小到0或者从0增大到正常布局大小,我们下面的ScrollTabView则对应改变marginTop。同时向上或者同时向下回来,则达到了吸顶的效果。可能语言表述比较苍白,下面看一下代码。


    render() {
        return (
            <View style={styles.container}>
                {this._renderHeader()}   //上方的头
                {this.renderScrollTab()} //下面的ScrollTabView

            </View>
        )

    }
/**
     * 渲染头部
     * @private
     */
    _renderHeader() {
        let icon = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1496299246419&di=f6d9e7d99236cb4319782d95cbd7f740&imgtype=0&src=http%3A%2F%2Fwww.pptbz.com%2FSoft%2FUploadSoft%2F200911%2F2009110521380826.jpg';
        let icon2 = 'http://pic28.nipic.com/20130503/9252150_153601831000_2.jpg';
        return (
            <ImageBackground
                ref={'_title'}
                style={styles.headerContainer}
                source={{uri: icon2}}>
                <View style={{flexDirection: 'row'}}>
                    <Image
                        style={{width: 30, height: 30}}
                        source={{uri: icon}}
                    />
                    <View>
                        <Text allowFontScaling={false} style={{color: 'white'}}>苹果旗舰店</Text>
                        <Text allowFontScaling={false} style={{color: 'white'}}>此处是促销信息</Text>
                    </View>
                    <View>
                        <Text allowFontScaling={false} style={{color: 'white'}}>已有2000人关注</Text>
                    </View>
                </View>
            </ImageBackground>
        );
    }

//ScrollTabView
    renderScrollTab() {
        return (
            <View
                ref={'_scrolltab'}
                style={styles.scrollTab}>
                <ScrollableTabView
                    listKey='d' key='4'

                    style={{height: ScreenUtil.screenH}}
                    renderTabBar={() => <ScrollableTabBar/>}
                >
                    <TabPage listKey='a' key='1' tabLabel='Tab #1' onScroll={this.onScroll}/>
                    <TabPage listKey='b' key='2' tabLabel='Tab #2' onScroll={this.onScroll}/>
                    <TabPage listKey='c' key='3' tabLabel='Tab #3' onScroll={this.onScroll}/>
                </ScrollableTabView>
            </View>
        )
    }

相应的样式:

    headerContainer: {
        width: ScreenUtil.screenW,
        height: 100,
        position: 'absolute',
        top: 0,
        justifyContent: 'center'
    },
    scrollTab: {
        flex: 1,
        marginTop: 100

组件写好之后,我们监听ScrollView的滚动:

onScroll = (e) => {
        let {x, y} = e.nativeEvent.contentOffset;
        console.log(y);
        if (y <= 100) {
            this.refs._title.setNativeProps({

                style: {
                    top: -y
                }
            });
            this.refs._scrolltab.setNativeProps({
                style: {
                    marginTop: 100 - y
                }
            })
        } else {
            this.refs._title.setNativeProps({
                style: {
                    top: -100
                }
            });
            this.refs._scrolltab.setNativeProps({
                style: {
                    marginTop: 0
                }
            })
        }
    };

基本完成,其实主要是思路想对了就好写了,代码不算复杂。
下面上github的地址,我还大方的送了一个封装好的NavigationBar组件,没有合适的标题栏用的可以直接拿去。
项目代码地址

猜你喜欢

转载自blog.csdn.net/u011272795/article/details/80714894