In APP, it is inevitable to use TAB components, some of which are TAB switching and some of which are TAB classification switching.

These components fall into the following two categories.

The first is very simple, and most third-party components can do the job. Here we focus on the second component, which not only slides left and right, but also slides automatically when clicked, to the center of the click.

To prepare

Let’s start with a wave. What is the status of a sliding component on the APP?

As you can see here, the TAB component needs to take into account screens that are longer than the APP and be able to slide after that.

Figure out how far you need to slide the current position to center it. Position to slide = left margin of click position -APP screen /2+ click position width /2

This formula is the core of our automatic sliding.

The development of

Using the ScrollView component to hold tabs makes it very easy to slide. At the same time add horizontal, directionalLockEnabled, showsHorizontalScrollIndicator, snapToAlignment several properties.

<ScrollView ref={e => this.scroll = e} horizontal directionalLockEnabled showsHorizontalScrollIndicator={false} SnapToAlignment ="center"> {this.props.data.map((item, index) => {/* specific item */})} </ScrollView>Copy the code

Wrap the content items with TouchableOpacity and call the setLaout method to record the width and height properties of each item for later calculation of the current position.

<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>
Copy the code

Record the rendered position of each item and store these values in variables for later calculation.

laout_list = []
setLaout(layout, index) {
    // The location of the deposit item
    this.laout_list[index] = layout;
    // Calculate the total length of all items
    this.scrollW += layout.width;
}
Copy the code

Next is the calculation of automatic position change click.

setIndex(index, bl = trueThis.setstate ({index}) // Compatibility errorif(! this.scroll)return; // Get the location data of the current itemlet layout = this.laout_list[index];
    letrx = deviceWidth / 2; / / formulaletsx = layout.x - rx + layout.width / 2; If you don't need to move yet, stay where you areif(sx < 0) sx = 0; Sx < this.scrollw -deviceWidth && this.scroll. ScrollTo ({x: sx, animated: bl}); Sx >= this.scrollw -deviceWidth && this.scroll. ScrollToEnd ({animated: bl}); sx >= this.scrollw -deviceWidth && this.scroll. // Trigger some needed external events this.props. OnChange && this.props. }Copy the code

Last result:

Gitee address

Making the address