import React, { Component } from 'react' import { View, Text, StyleSheet, TouchableOpacity, Image, ScrollView, TouchableHighlight, Keyboard } from 'react-native'; import BottomSheet from 'reanimated-bottom-sheet' import Animated from 'react-native-reanimated'; import { px2dp, height, size, onePx, colors, toast } from '../../utils/base' interface Props { options: Array; isInTab?: boolean; onChange: Function; themeColor?: string; headerText?: string; disableReason?: string; }; interface T { name: string; key: number; disable?: boolean }; export default class ActionSheet extends Component { constructor(props: Props) { super(props); // const state = redux.getState(); this.state = { height: height, }; this.renderInner = this.renderInner.bind(this) this._onCloseEnd = this._onCloseEnd.bind(this); }; public actionSheetHeaderHeight = px2dp(60); public decButtomOutLineWidth = px2dp(8) public sheetContainerRef = null; public sheetRef = null; public delayShow = null; public fall = new Animated.Value(1); public delayTimer = null; public delayHideTimer = null; componentWillUnmount() { this.delayTimer && clearTimeout(this.delayTimer); this.delayHideTimer && clearTimeout(this.delayHideTimer); }; public handleHide = () => { this.sheetRef.snapTo(0); this.sheetRef.snapTo(0); this.delayHideTimer = setTimeout(() => { this._onCloseEnd(); }, 250); }; public show = () => { //打开下拉框 Keyboard.dismiss(); this.delayHideTimer && clearTimeout(this.delayHideTimer); this.sheetContainerRef.setNativeProps({ style: { display: 'flex', zIndex: 999 } }); this.sheetRef.snapTo(1); this.sheetRef.snapTo(1); }; public _onCloseEnd = () => { this.sheetContainerRef.setNativeProps({ style: { display: 'none', zIndex: -1 } }); }; calculatSheetHeight() { const { isInTab = false, options = [{ name: '暂无数据', key: 1 }] } = this.props; //null safety //@ts-ignore const { height } = this.state; let maxHeight = height * 0.7; if (isInTab) { maxHeight = height * 0.7 - size.tab_height; } let contentHeight = this.actionSheetHeaderHeight + options.length * px2dp(53) + this.decButtomOutLineWidth + px2dp(60) if (contentHeight > maxHeight) { let callBackData = { sheetHeight: maxHeight, dargable: false } return callBackData } else { let callBackData = { sheetHeight: contentHeight, dargable: true } return callBackData }; }; handleChange = (option, index) => { this.handleHide(); const { onChange, disableReason } = this.props; if (option.disable) { return toast(disableReason); } this.delayTimer = setTimeout(() => { onChange && onChange(index, option); }, 100); }; public render_option = (option: T, index: number | undefined, len: number | undefined) => { const { onChange, themeColor = '#333' } = this.props; return ( this.handleChange(option, index)} style={[styles.optionLine, index === len - 1 ? { borderBottomColor: '#fff' } : null]} key={index + ''}> {option.name} ) }; renderInner() { const { options, headerText } = this.props; const { sheetHeight, dargable } = this.calculatSheetHeight(); // alert(sheetHeight) return ( {headerText ? headerText : '请选择'} { dargable ? options && options.map((option, index) => this.render_option(option, index, options.length)) : {options && options.map((option, index) => this.render_option(option, index, options.length))} } this.handleHide()} style={styles.decBtn}> 取消 ) }; render() { const { isInTab = false, options = [{ name: '暂无数据', key: 1 }] } = this.props; //null safety const { sheetHeight, dargable } = this.calculatSheetHeight(); return ( this.sheetContainerRef = c} style={styles.sheetContainer}> this.handleHide()} style={styles.touchOverlayContent}> { this.sheetRef = c }} borderRadius={px2dp(12)} onCloseEnd={this._onCloseEnd} /> ) } }; const styles = StyleSheet.create({ sheetContainer: { position: 'absolute', top: 0, left: 0, height: '100%', width: '100%', display: 'none', zIndex: -1 }, touchOverlayContent: { width: '100%', height: '100%', }, overlay: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, width: '100%', height: '100%', backgroundColor: 'rgba(0,0,0,0.7)', // zIndex: 0 }, sheetheader: { width: '100%', height: px2dp(60), borderBottomColor: '#eee', borderBottomWidth: onePx, justifyContent: 'center', alignItems: 'center' }, decBtn: { width: '100%', height: px2dp(60), justifyContent: 'center', alignItems: 'center', borderTopColor: "#f2f2f2", // backgroundColor: 'red' }, optionLine: { width: '100%', height: px2dp(52), justifyContent: 'center', alignItems: 'center', borderBottomColor: '#eee', borderBottomWidth: onePx, marginBottom: 1 } })