react-native仿微信侧栏字母组件开发(原理篇)

参考:https://github.com/sunnylqm/react-native-alphabetlistview/blob/master/components/SectionList.js

原理

通过触摸点的位置,去计算所在的字母。

源码

import React, { Component } from 'react';
import {
    AppRegistry,
    Dimensions,
    StyleSheet,
    View,
    Text,
    Button,
    Image,
    ToastAndroid,
    TouchableWithoutFeedback,
} from 'react-native';
let ScreenWidth = Dimensions.get('window').width;
let ScreenHeight = Dimensions.get('window').height;
const returnTrue = () => true;



class TestScreen extends React.Component {

  constructor(props, context) {
    super(props);
    this.select_nav = this.select_nav.bind(this);
    this.select_null = null;
  }

  select_nav(e){ //滑动触发事件
    // 输出当前 view
    const ev = e.nativeEvent.touches[0]; //获取多个触摸事件的第一个。比如你放了三根手指在屏幕上,他只算第一个放到屏幕上的
    const targetY = ev.pageY; //动态获取屏幕上触摸点垂直方向的距离
    const localY = ev.locationY; //第一次触摸到屏幕上距离顶部的距离
    const { y, width, height } = this.measure;
    this.getZM(y,targetY); //定位字母,并且触发相应的事件

  }

  resetSection() {
    this.select_null = null;
  }

  fixSectionItemMeasure() {
    const sectionItem = this.refs.view;
    if (!sectionItem) {
      return;
    }
    this.measureTimer = setTimeout(() => {
      sectionItem.measure((x, y, width, height, pageX, pageY) => {
        //console.log([x, y, width, height, pageX, pageY]);
        this.measure = {
          y: pageY,
          width,
          height
        };
      })
    }, 0);
  }

  getZM(topHeight,currentHeight){ //定位字母 topHeight:外层元素到顶部的距离 currentHeight:当前触摸点距离y高度
    var zm=['A','B','C'];
    var navItemHeight=50;//字母行高 如果有边框请注意把边框也加上
    var navHeight=navItemHeight*zm.length; //计算字母导航高度
    var indexNav=Math.ceil((currentHeight-topHeight)/navItemHeight)-1;
    // 触发相应的事件 比如切换state
    // ...

    if (zm[indexNav]) {
      console.log(zm[indexNav]);
      // console.log(currentHeight+"="+navHeight);
      return zm[indexNav];
    }
    else{
      console.log('null');
    }

  }
  componentDidMount() {
    this.fixSectionItemMeasure();
  }

  // fix bug when change data
  componentDidUpdate() {
    this.fixSectionItemMeasure();
  }

  componentWillUnmount() {
    this.measureTimer && clearTimeout(this.measureTimer);
  }

  //给最外层的view增加一个
  render() {
    return (

      
        测试A
        测试B
        测试C
            
    );
  }
}

const styles = StyleSheet.create({
  container:{
    marginTop:50,
    width:80,
    marginLeft:50,
    borderWidth:1,
    borderColor:"#000",
  },
  icon: {
    width: 25,
    height: 25,
  },
  oit:{
    height:50,
  },
});



module.exports = TestScreen;

你可能感兴趣的:(react-native仿微信侧栏字母组件开发(原理篇))