67

react native动态姿态tab组件

 5 years ago
source link: http://www.10tiao.com/html/275/201807/2653646436/2.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在APP中免不了要使用tab组件,有的是tab切换,也有的是tab分类切换。


这些组件分成下面两种:



第一种非常简单,同时大多数第三方组件都能达到效果。这里重点讲述第二种,我们要让第二种组件不仅能左右滑动,同时还能够在点击的时候自动滑动,将点击的位置滑动到正中间。


准备


我们先来分析一波.一个滑动组件在APP上是一种什么状态。


这里可以看出,tab组件需要考虑到长度超过APP的屏幕,并且在超过之后能够滑动。


同时计算出当前位置需要滑动多少距离才能够将位置居中。


需要滑动的位置=点击位置的左边距-APP屏幕/2+点击位置的宽度/2


这个公式也就是我们自动滑动的核心了。


开发


使用ScrollView组件承载tab项,这样就可以非常简单的达到滑动的效果。同时添加horizontaldirectionalLockEnabledshowsHorizontalScrollIndicatorsnapToAlignment几个属性。


<ScrollView ref={e => this.scroll = e}
    horizontal directionalLockEnabled
    showsHorizontalScrollIndicator={false}
    snapToAlignment="center">
    {this.props.data.map((item, index) =>
        {/*具体项*/}
    )}
</ScrollView>


使用TouchableOpacity包裹内容项,同时调用setLaout方法将每个项的宽高等属性记录下来,为我们后面计算当前位置做准备。


<TouchableOpacity onPress={() => this.setIndex(index)} 
    onLayout={e => this.setLaout(e.nativeEvent.layout, index)} 
    key={item.id} 
    style={tabBarStyle.itemBtn}>        
       <Text style={[tabBarStyle.item, this.state.index === index ? tabBarStyle.active : null]} > {item.name}</Text>        <View style={[tabBarStyle.line, this.state.index === index ? tabBarStyle.active2 : null]}>             </View>

</TouchableOpacity>


记录每个项渲染之后的位置,将这些值存在变量里,为后面计算做准备。


laout_list = []
setLaout(layout, index) {    //存单个项的位置
    this.laout_list[index] = layout;    //计算所有项的总长度
    this.scrollW += layout.width;
}


接下来就是点击自动变换位置的计算了。


setIndex(index, bl = true) {
   //先改变点击项的颜色    this.setState({ index })
   //兼容错误    if (!this.scroll) return;
   //拿到当前项的位置数据    let layout = this.laout_list[index];    let rx = deviceWidth / 2;
   //公式    let sx = layout.x - rx + layout.width / 2;
   //如果还不需要移动,原地待着    if (sx < 0) sx = 0;
   //移动位置    sx < this.scrollW - deviceWidth && this.scroll.scrollTo({ x: sx, animated: bl });
   //结尾部分直接移动到底    sx >= this.scrollW - deviceWidth && this.scroll.scrollToEnd({ animated: bl });
   //触发一些需要的外部事件    this.props.onChange && this.props.onChange(index); }


最后上一张结果图:



gitee地址:https://gitee.com/cuo9958/react-native-tabs


github地址:https://github.com/cuo9958/react-native-tabs-top


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK