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