感谢同事提供的店铺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组件,没有合适的标题栏用的可以直接拿去。
项目代码地址