美文网首页
通讯录-字母表索引ReactNative 2018-10-26

通讯录-字母表索引ReactNative 2018-10-26

作者: 槐树向北 | 来源:发表于2018-11-07 20:23 被阅读27次

通讯录旁边的字母表


import React, { Component } from 'react';

import {
    View,
    Text,
    findNodeHandle,
    UIManager
} from 'react-native';

import Const from '../base/Const';

export default class IndexerComponent extends Component {

    letterList = []; //字母索引

    constructor(props) {
        super(props);
        letterHeight = this.props && this.props.letterHeight ? parseInt(this.props.letterHeight) : Const.getSize(20);
        height = this.props && this.props.style && this.props.style.height ? this.props.style.height : 0;
        if (height != 0) {
            letterHeight = parseInt(height / 27);
        }
        this.state = {
            indexList: this.props && this.props.indexList,
            letterHeight: letterHeight,
            letterWidth: Const.getSize(20),
            textSize: this.props && this.props.letterSize ? this.props.letterSize : 0,
            textColor: this.props && this.props.textColor ? this.props.textColor : '#333333',
            bgColor: 'transparent'
        }
        this.generateLetterList();
    }

    generateLetterList() {
        this.letterList = [];
        for (let i = 65; i < 92; i++) {
            let letter = i !== 91 ? String.fromCharCode(i) : '#';
            this.letterList.push({
                isHighlight: this.state.indexList.indexOf(letter) !== -1 ? true : false,
                letter: letter
            });
        }

    }

    componentDidMount() {
        setTimeout(() => {
            this._getUILocation();
        }, 100);
    }

    componentWillReceiveProps(nextProps) {
        height = nextProps && nextProps.style && nextProps.style.height ? nextProps.style.height : 0;
        if (height != 0) {
            letterHeight = parseInt(height / 27);
        }
        this.setState({
            letterHeight: letterHeight,
            indexList: nextProps.indexList
        });
        this.generateLetterList();
    }

    componentDidUpdate() {
        setTimeout(() => {
            this._getUILocation();
        }, 100);
    }

    _getUILocation() {
        var handle = findNodeHandle(this.view);
        handle && UIManager.measure(handle, (x, y, width, height, pageX, pageY) => {
            this.pageX = pageX;
            this.pageY = pageY; //在屏幕中的位置
            this.height = height;   //有效區域高度
        })
    }


    _gestureHandlers = {
        onStartShouldSetResponder: () => true,  //對觸摸進行響應
        onMoveShouldSetResponder: () => true,  //對滑動進行響應
        onResponderGrant: (event) => {
            let index = parseInt(event.nativeEvent.pageY - this.pageY);
            index = Math.max(0, index);
            index = Math.min(this.height, index);
            index = parseInt(index / this.state.letterHeight);
            index = Math.min(this.letterList.length - 1, index);
            index = this.state.indexList.indexOf(this.letterList[index].letter);
            if (this.index != index && index !== -1) {
                this.index = index;
                this.onChange(index);
            }
            this.setState({
                bgColor: '#666'
            });
        }, //激活時做的動作
        onResponderMove: (event) => {
            let index = parseInt(event.nativeEvent.pageY - this.pageY);
            index = Math.max(0, index);
            index = Math.min(this.height, index);
            index = parseInt(index / this.state.letterHeight);
            index = Math.min(this.letterList.length - 1, index);
            index = this.state.indexList.indexOf(this.letterList[index].letter);
            if (this.index != index && index !== -1) {
                this.index = index;
                this.onChange(index);
            }
        },  //移動時作出的動作
        onResponderRelease: () => {
            this.index = -1;
            this.onChange(-1);
            this.setState({
                bgColor: 'transparent'
            });
        }, //動作釋放後做的動作
    }

    onChange(index) {
        this.props.onLetterChange && this.props.onLetterChange(index)
    }

    shouldComponentUpdate(nextProps) {
        if (nextProps.indexList || nextProps.letterHeight) {
            if (nextProps.indexList) {
                this.state.indexList = nextProps.indexList;
            }
            if (nextProps.letterHeight) {
                this.state.letterHeight = nextProps.letterHeight;
            }
            return true;
        }
        return false;
    }

    renderIndex() {
        return this.letterList.map((item, index) => {
            return this.renderIndexItem(item, index);
        })
    }

    renderIndexItem(item, index) {
        return <Text key={index} style={{
            lineHeight: this.state.letterHeight, width: this.state.letterWidth,
            fontSize: this.state.textSize, color: item.isHighlight ? '#333' : '#999',
            textAlign: 'center', textAlignVertical: 'center', backgroundColor: 'transparent'
        }}>{item.letter}</Text>
    }

    render() {
        return (
            <View
                style={{
                    justifyContent: 'center', alignItems: 'center', backgroundColor: 'transparent',
                    ...this.props.style
                }}
                ref={ref => this.view = ref}
                { ...this._gestureHandlers }>
                {this.renderIndex()}
            </View >
        );
    }
}

相关文章

网友评论

      本文标题:通讯录-字母表索引ReactNative 2018-10-26

      本文链接:https://www.haomeiwen.com/subject/xpjltqtx.html