2021-01-08-react native中实现时间轴移动

TimeLine组件:

index.js

import React from 'react';
import {
  View,
  Text,
  DeviceEventEmitter,
} from 'react-native';
import * as R from 'ramda';
import { PComponent } from 'rnplus';
import moment from 'moment';

import styles from './style';
import { timeLineLocation } from './func';

/**
 * 时间线
 */

class TimeLine extends PComponent {

  constructor (props) {
    super(props);
    this.state = {
      time: moment().format('HH:mm'),
    };
  }

  componentDidMount () {
    this.updateLocation();
    this.subscription = DeviceEventEmitter.addListener('ws_time', (time) => {
      this.setState({ time });
      this.updateLocation(); // 时间轴根据时间推移
    });
  }

  shouldComponentUpdate (nextProps, nextState) {
    return true;
  }

  componentWillReceiveProps (nextProps) {
  }

  componentWillUnmount () {
    this.subscription.remove();
  }

  // 时间变化,需要移动位置
  updateLocation = () => {
    const {
      timeLineStartTime = moment('2021-01-07 08:00'),
      interval=0,
    } = this.props;
    const timeLine = timeLineLocation(timeLineStartTime, interval);
    this.timeline.setNativeProps({
      style: {
        left: timeLine < 600 ? timeLine : timeLine - 225, // 提示信息在左边时减去信息长度
        // left: width,
      },
    });
  }

  render () {
    const { time } = this.state;
    const {
      unReachCountNow = false,
      timeLineStartTime = moment('2021-01-07 08:00'),
      timeLineContent ='请及时处理微波炉任务,超时后会自动消失',
      interval=0,
    } = this.props;
    const timeLine = timeLineLocation(timeLineStartTime, interval);
    // console.log('timeLine', timeLine);
    return (
      <View
        style={timeLine < 600 ? styles.time : styles.timeLeft}
        ref={timeline => (this.timeline = timeline)}
        pointerEvents="none"
      >
        <View style={timeLine < 600 ? styles.timeAndunReach : styles.timeAndunReachLeft}>
          <View style={styles.timeValue}>
            <Text style={styles.timeDesc}>{time}</Text>
          </View>
          {
            unReachCountNow ?
              <View style={timeLine < 600 ? styles.unReachCountValue : styles.unReachCountValueLeft}>
                <Text style={styles.timeDesc}>{timeLineContent}</Text>
              </View>
              : null
          }
        </View>
        <View style={timeLine < 600 ? styles.timeLine : styles.timeLineLeft} pointerEvents="none">
          {R.repeat('', 25).map(() => <Text style={styles.timeLineArea} />)}
        </View>
      </View>
    );
  }
}

export default TimeLine;

style.js

import { StyleSheet } from 'react-native';
import transPxToDp from 'rnx-ui/util/transPxToDp';

const pxCalculate = size => Math.round(transPxToDp(size));

export default StyleSheet.create({
  time: {
    width: pxCalculate(450),
    position: 'absolute',
    top: 0,
    zIndex: 999,
    flex:1,
  },
  timeValue: {
    width: pxCalculate(55),
    height: pxCalculate(25),
    borderRadius: pxCalculate(4),
    backgroundColor: 'rgb(55,197,56)',
    alignItems: 'flex-start',
    justifyContent: 'center',
  },
  unReachCountValue: {
    width: pxCalculate(400),
    backgroundColor: 'rgb(255,62,0)',
    height: pxCalculate(25),
    borderRadius: pxCalculate(4),
    alignItems: 'flex-start',
    justifyContent: 'center',
    marginLeft: pxCalculate(3)
  },
  timeDesc: {
    color: '#ffffff',
    fontSize: pxCalculate(20),
  },
  timeLine: {
    flex: 1,
    justifyContent: 'space-between',
    marginLeft: pxCalculate(27) // 时间轴的线定位到时间text的中间
  },
  timeLineArea: {
    width: pxCalculate(1),
    height: pxCalculate(3),
    marginTop: pxCalculate(2),
    // flex: 1,
    marginTop: pxCalculate(2),
    backgroundColor: '#FF0000',
  },
  timeAndunReach: {
    width: pxCalculate(450),
    flexDirection: 'row',
  },
  timeLeft: {
    // width: NEW_HOME_TIME_LINE_WIDTH,
    width: pxCalculate(900),
    position: 'absolute',
    top: 0,
    zIndex: 999,
    flex: 1,
    backgroundColor: 'transparent',
  },
  timeLineLeft: {
    flex: 1,
    justifyContent: 'space-between',
    marginLeft: pxCalculate(55), // 时间轴的线定位到时间text的中间
    alignSelf: 'center',
  },
  timeAndunReachLeft: {
    width: pxCalculate(900),
    flexDirection: 'row',
    marginLeft: pxCalculate(450),
  },
  unReachCountValueLeft: {
    marginLeft: pxCalculate(-463),
    width: pxCalculate(400),
    backgroundColor: 'rgb(255,62,0)',
    height: pxCalculate(25),
    borderRadius: pxCalculate(4),
    alignItems: 'flex-start',
    justifyContent: 'center',
  },
});

func.js

import moment from 'moment';
import {
  Dimensions
} from 'react-native';
const { width } = Dimensions.get('window');

export const timeLineLocation = (timeLineStartTime, interval) => {
  const hours = moment().hour();
  const minutes = moment().minute();
  const des = moment(timeLineStartTime).hour() * 60;
  const allMinutes = hours * 60 + minutes;

  const left = (width / interval) / 60 * (allMinutes - des ) - 5; // 位置 = left - 组件宽度 / 2
  return left;
};

TimeLine组件应用:

index.js

this.timeLineStartTime= moment('2021-01-07 07:00'); // 时间轴开始时间
this.timeLineEndTime=moment('2021-01-07 22:58'); // 时间轴结束时间
this.timeLineContent = '提示信息';
const { width } = Dimensions.get('window');
...
// 计算开始结束时间的整点数
intervalHours = (startTime, endTime) => {
  const startHour = moment(startTime).hour();
  const endMinute = moment(endTime).minute();
  const endHour = moment(endTime).hour() + (endMinute > 0 ? 1 : 0);
  return {
    startHour,
    endHour
  };
}

// 计算时间轴小时数
getHours = (startHour, endHour) => {
  const interval = endHour - startHour;
  return R.repeat('', interval).map((item, index) => `${index + startHour}:00`);
}
...

render() {
  const {
    timeLineStartTime,
    timeLineEndTime,
    timeLineContent,
  } = this;
  const {
    startHour = 0,
    endHour = 0,
  } = this.intervalHours(timeLineStartTime, timeLineEndTime);
  const interval = endHour - startHour; // 开始结束的时间差
  return (
    <View style={
   
   { width: width, flexDirection: 'row', justifyContent: 'space-around', backgroundColor: '#313D4F', display: 'inline' }}>
      {this.getHours(startHour, endHour).map(item => <Text style={styles.hour}>{item}</Text>)}
      {/* 时间段分割线 */}
      {R.repeat('', interval * 2).map((line, index) => <View style={[styles.line, { left: Number(index) * (width / (interval * 2)) + 10 }]} />)}
      <TimeLine
        unReachCountNow={unReachCountNow}
        timeLineStartTime={timeLineStartTime}
        timeLineEndTime={timeLineEndTime}
        timeLineContent={timeLineContent}
        interval={interval}
      />
    </View>
  )
}

style.js

  hour: {
    flex: 1,
    flexDirection: 'row',
    backgroundColor: 'transparent',
    color: '#ffffff',
    fontSize: pxCalculate(20),
    textAlignVertical: 'center',
    height: pxCalculate(70),
  },
  line: {
    position: 'absolute',
    bottom: 0,
    width: StyleSheet.hairlineWidth,
    backgroundColor: '#DDDDDD',
    height: pxCalculate(15),
  },

猜你喜欢

转载自blog.csdn.net/khadijiah/article/details/112349685