自定义SegmentView控件

2020-01-16  本文已影响0人  6灰太狼9

先上效果图


gif5新文件.gif

可以通过属性修改选中颜色、默认颜色和默认选择项,以及控制底部标示的显示与否和动画时间。

代码

import React,{Component} from 'react';
import {View,Text,StyleSheet,Dimensions,TouchableHighlight,Animated,Easing} from 'react-native';
import PropsTypes from 'prop-types';
const {width,height} = Dimensions.get('window');
export default class SegmentView extends Component{

    //定义属性的类型
    static propTypes = {
        titles: PropsTypes.array,
        selectedIndex:PropsTypes.number,
        defaultColor:PropsTypes.string,
        selectColor:PropsTypes.string,
        showSign:PropsTypes.bool,
        callBack:PropsTypes.func,
        animationDuring:PropsTypes.number,
    }
    //定义属性的默认值
    static defaultProps = {
        selectedIndex:0,
        defaultColor:'#333',
        selectColor:'#FE9540',
        showSign:true,
        animationDuring:100,
    }

    constructor(props){
        super(props);

        this.state = {
            selectedIndex:props.selectedIndex,
            signViewLeft:new Animated.Value(props.selectedIndex*width/props.titles.length),
        }
    }


    _renderSignView(){
        if (this.props.showSign) {
            return <Animated.View style={[{left:this.state.signViewLeft,width:width/this.props.titles.length,backgroundColor:this.props.selectColor},styles.signView]}></Animated.View>
        }
    }

    render() {
        return(
            <View style = {styles.container}>
                {this.props.titles.map((item,i)=>{
                    return (
                        <TouchableHighlight 
                        key = {i}
                        style={styles.itemView}
                        underlayColor='#fff'
                        onPress={this._onpressItem.bind(this,i)}
                        >
                            <Text style={{color:i==this.state.selectedIndex?this.props.selectColor:this.props.defaultColor,fontSize:16}}>{item}</Text>
                        </TouchableHighlight>  
                    );
                })}
                {this._renderSignView()}
            </View>
        )
    }
    _onpressItem(i){
        this.setSelectIndex(i);
        if (this.props.callBack) {
            this.props.callBack(i);
        }
    }

    //外部调用这个方法可以修改选中项
    setSelectIndex(index){
        if (index==this.state.selectedIndex) {
            return;
        }
        this.setState({
            selectedIndex:index,
        },()=>{
            if (this.props.showSign) {
                Animated.timing(
                    this.state.signViewLeft,
                    {
                        toValue:this.state.selectedIndex*width/this.props.titles.length,
                        duration: this.props.animationDuring,
                        easing: Easing.linear,
                    }
                ).start();
            }
        });
    }

}


const styles = StyleSheet.create({
    container:{
        height:50,
        width:'100%',
        backgroundColor:'#fff',
        flexDirection:'row',
        alignItems:'center',
    },
    itemView:{
        height:'100%',
        flex: 1,
        justifyContent:'center',
        alignItems:'center',
    },
    signView:{
        height:1,
        position:'absolute',
        bottom:0,
    }
});

用法

<SegmentView 
                titles={['1','2','3']}
                selectedIndex = {2}
                showSign={true}
                callBack={(i)=>{
                    console.warn(i);
                }}
                ref={r=>{this.segment=r}}
                ></SegmentView>
上一篇 下一篇

猜你喜欢

热点阅读