在APP中免不了要使用tab組件,有的是tab切換,也有的是tab分類切換.javascript
這些組件分紅下面兩種.java
第一種很是簡單,同時大多數第三方組件都能達到效果.這裏重點講述第二種,咱們要讓第二種組件不只能左右滑動,同時還可以在點擊的時候自動滑動,將點擊的位置滑動到正中間.react
咱們先來分析一波.一個滑動組件在APP上是一種什麼狀態.git
這裏能夠看出,tab組件須要考慮到長度超過APP的屏幕,而且在超過以後可以滑動.github
同時計算出當前位置須要滑動多少距離纔可以將位置居中.須要滑動的位置=點擊位置的左邊距-APP屏幕/2+點擊位置的寬度/2
react-native
這個公式也就是咱們自動滑動的核心了.this
使用ScrollView
組件承載tab項,這樣就能夠很是簡單的達到滑動的效果.同時添加horizontal
、directionalLockEnabled
、showsHorizontalScrollIndicator
、snapToAlignment
幾個屬性.spa
<ScrollView ref={e => this.scroll = e} horizontal directionalLockEnabled showsHorizontalScrollIndicator={false} snapToAlignment="center"> {this.props.data.map((item, index) => {/*具體項*/} )} </ScrollView>
使用TouchableOpacity
包裹內容項,同時調用setLaout
方法將每一個項的寬高等屬性記錄下來,爲咱們後面計算當前位置作準備.code
<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>
記錄每一個項渲染以後的位置,將這些值存在變量裏,爲後面計算作準備.blog
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); }
最後上一張結果圖: