如何安装tracker(封装Picker组件)
如何安装tracker(封装Picker组件)
2024-11-22 04:37:27  作者:囬忆好美  网址:https://m.xinb2b.cn/tech/bxv207939.html

import { View, Text, TouchableWithoutFeedback, TouchableOpacity, FlatList,} from 'react-native'import React,{ PureComponent, Component,} from 'react'import _ from 'lodash'import styleSheet, {getThemeColor} from '../utils/styleSheet'import {Callback} from "modern/types/lang";import Modal from './Modal'import {getScreenHeight, getScreenWidth} from "modern/consts/ui-common";const styles = styleSheet.create({ container:{ flex:1, backgroundColor: 0x00000074, alignItems: 'center', justifyContent: 'flex-end', }, contentView:{ flexDirection:'row', justifyContent: 'space-around', backgroundColor: 'white' }, stage:{ top:0, bottom:0, left:0, right:0, position:'absolute', zIndex:10, flexDirection:'row', justifyContent: 'space-around', }, maskView:{ left:0, right:0, position:'absolute', top:0, bottom:0, zIndex:0, justifyContent:'space-between' }, emptyView:{ height:50, flexDirection:'row', justifyContent:'space-between', paddingHorizontal:20, backgroundColor: 'white', }, maskStyle:{ width:'100%', // backgroundColor:'rgba(232,232,232,0.9)', borderColor:"rgba(232,232,232,0.9)", backgroundColor:'white' }, midMaskStyle:{ backgroundColor:'#f9f9f9' }, headerBtnView:{ height:50,justifyContent: 'center' }, cancelText:{ fontSize:16,color:'gray' }})function DefaultView (){ return ( <View style={{flex:1,justifyContent:'center',alignItems: 'center'}}> <Text>暂无数据</Text> </View> )}interface ISHeadProps { customHead:any, confirm:Callback, hide:Callback, headOptions:any}const Head:React.FC<ISHeadProps> = React.memo(({customHead,confirm,hide,headOptions})=>{ if(customHead && _.isFunction(customHead)){ return customHead(confirm,hide) } const { cancelTextStyle={}, cancelBtnView={}, confirmBtnView={}, confirmTextStyle={}, leftText='取消', rightText='确定', headerContainView={}, } = headOptions return <View style={[styles.emptyView,headerContainView]}> <TouchableOpacity style={[styles.headerBtnView,cancelBtnView]} onPress={hide}> <Text style={[styles.cancelText,cancelTextStyle]}>{leftText}</Text> </TouchableOpacity> <TouchableOpacity onPress={confirm} style={[styles.headerBtnView,confirmBtnView]}> <Text style={[{color:getThemeColor(),fontSize:16},confirmTextStyle]}>{rightText}</Text> </TouchableOpacity> </View>})interface ISEmpty { hide:Callback}const Empty:React.FC<ISEmpty> = React.memo(({hide})=>{ return <TouchableWithoutFeedback onPress={hide}> <View style={{flex:1,width:getScreenWidth()}} /> </TouchableWithoutFeedback>})interface ISMaskView { maxLength:number, itemHeihght:number, maskOptions:any,}const MaskView:React.FC<ISMaskView> = React.memo(({maxLength,itemHeihght,maskOptions={}})=>{ const { upMaskView, bottomMaskView, midMaskView } = maskOptions const mid = Math.floor(maxLength/2) return <View style={[styles.maskView]}> <View style={[styles.maskStyle,{height:itemHeihght*mid,borderBottomWidth:0.5,},upMaskView]}/> <View style={[styles.midMaskStyle,{height:itemHeihght},midMaskView]} /> <View style={[styles.maskStyle,{height:itemHeihght*mid,borderTopWidth:0.5,},bottomMaskView]}/> </View>})interface ISourceType { id:string, name:string, sub?:ISourceType[] [propname:string]:any,}interface ISitemOptons { itemHeihght?:number, maxLength?:5 | 7 | 9, ActiveTextStyle?:any, normalTextStyle?:any,}interface ISProps { sourceData:ISourceType[], cancel?:Callback, confirm:Callback, selectData:ISourceType[], pickerType:'scroll' | 'click' | 'all', customHead:any, headOptions:any, maskOptions:any, itemOptons:ISitemOptons, isLinkage:boolean, renderListEmptyComponent:Callback, emptyOptions:any, wrapOptions:any, EmptyView:any}interface ISState { visible:boolean, floor:number,}function WithHeadAndMethod(WrapComponent:any){ return class PickerAlertView extends PureComponent<ISProps,ISState>{ public selectedData:ISourceType[] =[] public static defaultProps = { itemOptons:{}, selectData:[], headOptions:{}, pickerType:'all', maskOptions:{}, isLinkage:false, emptyOptions:{}, wrapOptions:{ stageView:{} } } constructor(props:ISProps) { super(props); this.state = { visible:false, floor:this.getMaxFloor(), } } public getMaxFloor = ()=>{ const { sourceData,isLinkage } = this.props if(_.isEmpty(sourceData)) return 0 if(isLinkage) return sourceData.length let floor:number = 1 function treeData(arr:any){ const sub:any = arr.find((item:any)=>item?.sub?.length > 0) if(sub){ floor = floor 1 let arr2:any = [] arr.forEach((item:any)=>{ if(item?.sub?.length>0){ arr2 = arr2.concat(item.sub) } }) treeData(arr2) } } treeData(sourceData) return floor } public show = ()=>{ this.setState({visible:true}) } public confirm = ()=>{ const { confirm=_.noop } = this.props this.hide() confirm(this.selectedData) } public hide = ()=>{ const { cancel=_.noop } = this.props cancel() this.setState({visible:false}) } public getSelected = ()=>this.selectedData private setSelected = (item:ISourceType,floor:number)=>{ this.selectedData[floor] = item } public componentDidUpdate(preProps,prevState,snapshot){ if(!_.isEqual(this.props.sourceData,preProps.sourceData)){ this.setState({ floor:this.getMaxFloor() }) } } public render(){ const { visible, floor, } = this.state const { selectData, sourceData, pickerType, customHead, headOptions, maskOptions, itemOptons, isLinkage, renderListEmptyComponent, emptyOptions, wrapOptions, EmptyView = DefaultView } = this.props const { stageView } = wrapOptions if(!visible) return null const { maxLength=9, itemHeihght=50, ActiveTextStyle={}, normalTextStyle={} } = itemOptons return ( <Modal visible={visible} animationType="slide" transparent={true} > <View style={styles.container} > <Empty hide={this.hide}/> <View style={{ width:getScreenWidth()}}> <Head headOptions={headOptions} hide={this.hide} confirm={this.confirm} customHead={customHead} /> <View style={[{height:itemHeihght*maxLength},styles.contentView]}> <View style={[styles.stage,stageView]}>{ _.isEmpty(sourceData) ?<EmptyView/>: <WrapComponent sourceList={sourceData} setSelect={this.setSelected} floor={floor} currentFloor={0} maxLength={maxLength} defaultSelected = {selectData} itemHeihght={itemHeihght} ActiveTextStyle={ActiveTextStyle} normalTextStyle={normalTextStyle} pickerType={pickerType} originData={sourceData} isLinkage={isLinkage} renderListEmptyComponent={renderListEmptyComponent} emptyOptions={emptyOptions} />} </View> <MaskViewmaxLength={maxLength}itemHeihght={itemHeihght}maskOptions={maskOptions} /> </View> </View> </View> </Modal> ) } }}interface ISItemProps { sourceList:ISourceType[], setSelect:Callback, floor:number, currentFloor:number, maxLength: 5 | 7 | 9, defaultSelected:ISourceType[], itemHeihght:number, ActiveTextStyle:any, normalTextStyle:any, pickerType:string, isLinkage:boolean, originData:any, renderListEmptyComponent:Callback, emptyOptions:any}interface ISItemState { nextData:ISourceType[], currentChoose:ISourceType, initialScrollIndex:number, renderList:any[], surerefresh:any}class PickerAlertViewItem extends PureComponent<ISItemProps,ISItemState> { public scrollView:any public flatEl:any public currentItem:any public itemEL:any public config:any = { waitForInteraction: false, itemVisiblePercentThreshold:100, } public constructor(props:ISItemProps) { super(props); this.state = { nextData:this.defaultRenderList(), currentChoose:this.getDefaultChoose(), initialScrollIndex:this.getInitialScrollIndex(), renderList:this.flatListData(), surerefresh:null, } } public getInitialScrollIndex = ()=>{ const {defaultSelected,currentFloor,sourceList } = this.props if(_.isEmpty(defaultSelected)) return 0 const initIndex = sourceList.findIndex(item=>String(item.id) === String(defaultSelected[currentFloor]?.id)) return initIndex<0?0:initIndex } public defaultRenderList = ()=>{ const { currentFloor, floor, defaultSelected, sourceList,isLinkage,originData} = this.props if(isLinkage){ return originData[currentFloor 1] } const getNoFefault = ()=>this.props.sourceList?.[0]?.sub || [] const getDefaultList = ()=>{ if(currentFloor 1 === floor ) return [] return sourceList.find(value=>value.id === defaultSelected[currentFloor].id)?.sub || getNoFefault() } return _.isEmpty(defaultSelected)?getNoFefault():getDefaultList() } public getDefaultChoose = ()=>{ const { defaultSelected, currentFloor, sourceList } = this.props return _.isEmpty(defaultSelected)?sourceList?.[0]:(sourceList.find(item=>item.id === defaultSelected?.[currentFloor]?.id) || sourceList?.[0]) } public mid = ()=>{ const { maxLength } = this.props return Math.floor(maxLength/2) } public flatListData = (nextData:any[])=>{ const { sourceList,currentFloor,originData ,isLinkage} = this.props const mid = this.mid() const arr = Array(mid).fill({id:'',name:'',sub:[]}) let currentData = nextData?nextData:sourceList if(isLinkage){ currentData = originData[currentFloor] } if(currentData.length === 0 || !currentData) return [] return [...arr,...currentData,...arr] } public getItemLayout = (data:any,index:any) =>{ const { itemHeihght } = this.props return {length: itemHeihght, offset: itemHeihght * index, index} } public renderItem = ({item,index,separators}:any)=>{ const { itemHeihght ,ActiveTextStyle,normalTextStyle,pickerType} = this.props const {currentChoose} = this.state const itemPress = (pickerType === 'scroll' || item.id === currentChoose?.id)?_.noop:this.clickItem return <TouchableWithoutFeedback onPress={()=>itemPress(item,index)}> <Text numberOfLines={1} style={[ {height:itemHeihght,textAlign:'center',lineHeight:itemHeihght,opacity:0.8,paddingHorizontal: 10, }, item.id === currentChoose?.id?ActiveTextStyle:normalTextStyle ]} >{item.name}</Text> </TouchableWithoutFeedback> } public clickItem =(item:ISourceType,index:any)=>{ const mid = this.mid() if(index<mid) return if(!item) return this.scrollToIndex(index) this.chooseItem(index,item) } public scrollToIndex = (index:any)=>{ const { renderList } = this.state if(renderList.length === 0 || !renderList) return if(this.flatEl){ this.flatEl.scrollToIndex({ index, viewPosition:0.5, animated:true }) } } public chooseItem = (index:number,item:ISourceType)=>{ const { setSelect,currentFloor,isLinkage } = this.props setSelect(item,currentFloor) if(isLinkage) return this.setState({ currentChoose:item || {}, nextData:item?.sub || [] },()=>{ if(this.itemEL) this.itemEL.reduction() }) } public reduction=()=>{ const currentChoose = this.props.sourceList?.[0] || {} const nextData = currentChoose?.sub || [] const mid = this.mid() this.setState({ currentChoose, nextData, renderList:this.flatListData(), surerefresh:Date.now() Math.random(), }) } public componentDidMount(){ this.initSelected() } public componentDidUpdate(preProp:ISItemProps,preState:ISItemState){ const mid = this.mid() if(this.state.surerefresh !== preState.surerefresh){ _.delay(()=>this.clickItem(this.state.currentChoose,mid),100) } } public initSelected = ()=>{ const {setSelect,currentFloor } = this.props const { currentChoose } = this.state setSelect(currentChoose,currentFloor) if(this.flatEl) this.flatEl.recordInteraction() } public renderListEmptyComponent = (data:any)=>{ const {renderListEmptyComponent,itemHeihght,emptyOptions,maxLength} = this.props if(renderListEmptyComponent) return renderListEmptyComponent() return <View style={{height:itemHeihght*maxLength,justifyContent:'center',alignItems: 'center'}}> <Text numberOfLines={1} style={[ { height:itemHeihght, textAlign:'center', lineHeight:itemHeihght, opacity:0.8, paddingHorizontal: 10, } ]} >{emptyOptions.descText || '暂无数据'}</Text> </View> } public render(){ const { floor, currentFloor, setSelect, defaultSelected, maxLength, itemHeihght=50, ActiveTextStyle, normalTextStyle, pickerType, isLinkage, originData, emptyOptions, } = this.props const { nextData, initialScrollIndex, renderList, } = this.state const nextFloor = currentFloor 1 return ( <> <FlatList style={{flex:1}} ref={ref=>this.flatEl = ref} showsHorizontalScrollIndicator={false} showsVerticalScrollIndicator={false} keyExtractor={(item: object, index: number) => String(index)} renderItem={this.renderItem} viewabilityConfig={this.config} data={renderList} getItemLayout={this.getItemLayout} initialScrollIndex={initialScrollIndex} onMomentumScrollEnd={this._moveEnd} scrollEnabled={pickerType === 'click'?false:true} ListEmptyComponent={this.renderListEmptyComponent} /> { floor > nextFloor ? <PickerAlertViewItem ref={ref=>this.itemEL = ref} sourceList={nextData} floor={floor} setSelect={setSelect} currentFloor={nextFloor} defaultSelected={defaultSelected} maxLength={maxLength} itemHeihght={itemHeihght} ActiveTextStyle={ActiveTextStyle} normalTextStyle={normalTextStyle} pickerType={pickerType} isLinkage={isLinkage} originData={originData} emptyOptions={emptyOptions} />: null } </> ) } private _moveEnd=(e)=>{ const {itemHeihght} = this.props const { renderList } = this.state const contentOffset = e.nativeEvent.contentOffset.y; const mid = this.mid() const index = Math.round(contentOffset/itemHeihght) mid this.clickItem(renderList[index],index) }}export default WithHeadAndMethod(PickerAlertViewItem),今天小编就来说说关于如何安装tracker?下面更多详细答案一起来看看吧!


如何安装tracker

import { View, Text, TouchableWithoutFeedback, TouchableOpacity, FlatList,} from 'react-native'import React,{ PureComponent, Component,} from 'react'import _ from 'lodash'import styleSheet, {getThemeColor} from '../utils/styleSheet'import {Callback} from "modern/types/lang";import Modal from './Modal'import {getScreenHeight, getScreenWidth} from "modern/consts/ui-common";const styles = styleSheet.create({ container:{ flex:1, backgroundColor: 0x00000074, alignItems: 'center', justifyContent: 'flex-end', }, contentView:{ flexDirection:'row', justifyContent: 'space-around', backgroundColor: 'white' }, stage:{ top:0, bottom:0, left:0, right:0, position:'absolute', zIndex:10, flexDirection:'row', justifyContent: 'space-around', }, maskView:{ left:0, right:0, position:'absolute', top:0, bottom:0, zIndex:0, justifyContent:'space-between' }, emptyView:{ height:50, flexDirection:'row', justifyContent:'space-between', paddingHorizontal:20, backgroundColor: 'white', }, maskStyle:{ width:'100%', // backgroundColor:'rgba(232,232,232,0.9)', borderColor:"rgba(232,232,232,0.9)", backgroundColor:'white' }, midMaskStyle:{ backgroundColor:'#f9f9f9' }, headerBtnView:{ height:50,justifyContent: 'center' }, cancelText:{ fontSize:16,color:'gray' }})function DefaultView (){ return ( <View style={{flex:1,justifyContent:'center',alignItems: 'center'}}> <Text>暂无数据</Text> </View> )}interface ISHeadProps { customHead:any, confirm:Callback, hide:Callback, headOptions:any}const Head:React.FC<ISHeadProps> = React.memo(({customHead,confirm,hide,headOptions})=>{ if(customHead && _.isFunction(customHead)){ return customHead(confirm,hide) } const { cancelTextStyle={}, cancelBtnView={}, confirmBtnView={}, confirmTextStyle={}, leftText='取消', rightText='确定', headerContainView={}, } = headOptions return <View style={[styles.emptyView,headerContainView]}> <TouchableOpacity style={[styles.headerBtnView,cancelBtnView]} onPress={hide}> <Text style={[styles.cancelText,cancelTextStyle]}>{leftText}</Text> </TouchableOpacity> <TouchableOpacity onPress={confirm} style={[styles.headerBtnView,confirmBtnView]}> <Text style={[{color:getThemeColor(),fontSize:16},confirmTextStyle]}>{rightText}</Text> </TouchableOpacity> </View>})interface ISEmpty { hide:Callback}const Empty:React.FC<ISEmpty> = React.memo(({hide})=>{ return <TouchableWithoutFeedback onPress={hide}> <View style={{flex:1,width:getScreenWidth()}} /> </TouchableWithoutFeedback>})interface ISMaskView { maxLength:number, itemHeihght:number, maskOptions:any,}const MaskView:React.FC<ISMaskView> = React.memo(({maxLength,itemHeihght,maskOptions={}})=>{ const { upMaskView, bottomMaskView, midMaskView } = maskOptions const mid = Math.floor(maxLength/2) return <View style={[styles.maskView]}> <View style={[styles.maskStyle,{height:itemHeihght*mid,borderBottomWidth:0.5,},upMaskView]}/> <View style={[styles.midMaskStyle,{height:itemHeihght},midMaskView]} /> <View style={[styles.maskStyle,{height:itemHeihght*mid,borderTopWidth:0.5,},bottomMaskView]}/> </View>})interface ISourceType { id:string, name:string, sub?:ISourceType[] [propname:string]:any,}interface ISitemOptons { itemHeihght?:number, maxLength?:5 | 7 | 9, ActiveTextStyle?:any, normalTextStyle?:any,}interface ISProps { sourceData:ISourceType[], cancel?:Callback, confirm:Callback, selectData:ISourceType[], pickerType:'scroll' | 'click' | 'all', customHead:any, headOptions:any, maskOptions:any, itemOptons:ISitemOptons, isLinkage:boolean, renderListEmptyComponent:Callback, emptyOptions:any, wrapOptions:any, EmptyView:any}interface ISState { visible:boolean, floor:number,}function WithHeadAndMethod(WrapComponent:any){ return class PickerAlertView extends PureComponent<ISProps,ISState>{ public selectedData:ISourceType[] =[] public static defaultProps = { itemOptons:{}, selectData:[], headOptions:{}, pickerType:'all', maskOptions:{}, isLinkage:false, emptyOptions:{}, wrapOptions:{ stageView:{} } } constructor(props:ISProps) { super(props); this.state = { visible:false, floor:this.getMaxFloor(), } } public getMaxFloor = ()=>{ const { sourceData,isLinkage } = this.props if(_.isEmpty(sourceData)) return 0 if(isLinkage) return sourceData.length let floor:number = 1 function treeData(arr:any){ const sub:any = arr.find((item:any)=>item?.sub?.length > 0) if(sub){ floor = floor 1 let arr2:any = [] arr.forEach((item:any)=>{ if(item?.sub?.length>0){ arr2 = arr2.concat(item.sub) } }) treeData(arr2) } } treeData(sourceData) return floor } public show = ()=>{ this.setState({visible:true}) } public confirm = ()=>{ const { confirm=_.noop } = this.props this.hide() confirm(this.selectedData) } public hide = ()=>{ const { cancel=_.noop } = this.props cancel() this.setState({visible:false}) } public getSelected = ()=>this.selectedData private setSelected = (item:ISourceType,floor:number)=>{ this.selectedData[floor] = item } public componentDidUpdate(preProps,prevState,snapshot){ if(!_.isEqual(this.props.sourceData,preProps.sourceData)){ this.setState({ floor:this.getMaxFloor() }) } } public render(){ const { visible, floor, } = this.state const { selectData, sourceData, pickerType, customHead, headOptions, maskOptions, itemOptons, isLinkage, renderListEmptyComponent, emptyOptions, wrapOptions, EmptyView = DefaultView } = this.props const { stageView } = wrapOptions if(!visible) return null const { maxLength=9, itemHeihght=50, ActiveTextStyle={}, normalTextStyle={} } = itemOptons return ( <Modal visible={visible} animationType="slide" transparent={true} > <View style={styles.container} > <Empty hide={this.hide}/> <View style={{ width:getScreenWidth()}}> <Head headOptions={headOptions} hide={this.hide} confirm={this.confirm} customHead={customHead} /> <View style={[{height:itemHeihght*maxLength},styles.contentView]}> <View style={[styles.stage,stageView]}>{ _.isEmpty(sourceData) ?<EmptyView/>: <WrapComponent sourceList={sourceData} setSelect={this.setSelected} floor={floor} currentFloor={0} maxLength={maxLength} defaultSelected = {selectData} itemHeihght={itemHeihght} ActiveTextStyle={ActiveTextStyle} normalTextStyle={normalTextStyle} pickerType={pickerType} originData={sourceData} isLinkage={isLinkage} renderListEmptyComponent={renderListEmptyComponent} emptyOptions={emptyOptions} />} </View> <MaskViewmaxLength={maxLength}itemHeihght={itemHeihght}maskOptions={maskOptions} /> </View> </View> </View> </Modal> ) } }}interface ISItemProps { sourceList:ISourceType[], setSelect:Callback, floor:number, currentFloor:number, maxLength: 5 | 7 | 9, defaultSelected:ISourceType[], itemHeihght:number, ActiveTextStyle:any, normalTextStyle:any, pickerType:string, isLinkage:boolean, originData:any, renderListEmptyComponent:Callback, emptyOptions:any}interface ISItemState { nextData:ISourceType[], currentChoose:ISourceType, initialScrollIndex:number, renderList:any[], surerefresh:any}class PickerAlertViewItem extends PureComponent<ISItemProps,ISItemState> { public scrollView:any public flatEl:any public currentItem:any public itemEL:any public config:any = { waitForInteraction: false, itemVisiblePercentThreshold:100, } public constructor(props:ISItemProps) { super(props); this.state = { nextData:this.defaultRenderList(), currentChoose:this.getDefaultChoose(), initialScrollIndex:this.getInitialScrollIndex(), renderList:this.flatListData(), surerefresh:null, } } public getInitialScrollIndex = ()=>{ const {defaultSelected,currentFloor,sourceList } = this.props if(_.isEmpty(defaultSelected)) return 0 const initIndex = sourceList.findIndex(item=>String(item.id) === String(defaultSelected[currentFloor]?.id)) return initIndex<0?0:initIndex } public defaultRenderList = ()=>{ const { currentFloor, floor, defaultSelected, sourceList,isLinkage,originData} = this.props if(isLinkage){ return originData[currentFloor 1] } const getNoFefault = ()=>this.props.sourceList?.[0]?.sub || [] const getDefaultList = ()=>{ if(currentFloor 1 === floor ) return [] return sourceList.find(value=>value.id === defaultSelected[currentFloor].id)?.sub || getNoFefault() } return _.isEmpty(defaultSelected)?getNoFefault():getDefaultList() } public getDefaultChoose = ()=>{ const { defaultSelected, currentFloor, sourceList } = this.props return _.isEmpty(defaultSelected)?sourceList?.[0]:(sourceList.find(item=>item.id === defaultSelected?.[currentFloor]?.id) || sourceList?.[0]) } public mid = ()=>{ const { maxLength } = this.props return Math.floor(maxLength/2) } public flatListData = (nextData:any[])=>{ const { sourceList,currentFloor,originData ,isLinkage} = this.props const mid = this.mid() const arr = Array(mid).fill({id:'',name:'',sub:[]}) let currentData = nextData?nextData:sourceList if(isLinkage){ currentData = originData[currentFloor] } if(currentData.length === 0 || !currentData) return [] return [...arr,...currentData,...arr] } public getItemLayout = (data:any,index:any) =>{ const { itemHeihght } = this.props return {length: itemHeihght, offset: itemHeihght * index, index} } public renderItem = ({item,index,separators}:any)=>{ const { itemHeihght ,ActiveTextStyle,normalTextStyle,pickerType} = this.props const {currentChoose} = this.state const itemPress = (pickerType === 'scroll' || item.id === currentChoose?.id)?_.noop:this.clickItem return <TouchableWithoutFeedback onPress={()=>itemPress(item,index)}> <Text numberOfLines={1} style={[ {height:itemHeihght,textAlign:'center',lineHeight:itemHeihght,opacity:0.8,paddingHorizontal: 10, }, item.id === currentChoose?.id?ActiveTextStyle:normalTextStyle ]} >{item.name}</Text> </TouchableWithoutFeedback> } public clickItem =(item:ISourceType,index:any)=>{ const mid = this.mid() if(index<mid) return if(!item) return this.scrollToIndex(index) this.chooseItem(index,item) } public scrollToIndex = (index:any)=>{ const { renderList } = this.state if(renderList.length === 0 || !renderList) return if(this.flatEl){ this.flatEl.scrollToIndex({ index, viewPosition:0.5, animated:true }) } } public chooseItem = (index:number,item:ISourceType)=>{ const { setSelect,currentFloor,isLinkage } = this.props setSelect(item,currentFloor) if(isLinkage) return this.setState({ currentChoose:item || {}, nextData:item?.sub || [] },()=>{ if(this.itemEL) this.itemEL.reduction() }) } public reduction=()=>{ const currentChoose = this.props.sourceList?.[0] || {} const nextData = currentChoose?.sub || [] const mid = this.mid() this.setState({ currentChoose, nextData, renderList:this.flatListData(), surerefresh:Date.now() Math.random(), }) } public componentDidMount(){ this.initSelected() } public componentDidUpdate(preProp:ISItemProps,preState:ISItemState){ const mid = this.mid() if(this.state.surerefresh !== preState.surerefresh){ _.delay(()=>this.clickItem(this.state.currentChoose,mid),100) } } public initSelected = ()=>{ const {setSelect,currentFloor } = this.props const { currentChoose } = this.state setSelect(currentChoose,currentFloor) if(this.flatEl) this.flatEl.recordInteraction() } public renderListEmptyComponent = (data:any)=>{ const {renderListEmptyComponent,itemHeihght,emptyOptions,maxLength} = this.props if(renderListEmptyComponent) return renderListEmptyComponent() return <View style={{height:itemHeihght*maxLength,justifyContent:'center',alignItems: 'center'}}> <Text numberOfLines={1} style={[ { height:itemHeihght, textAlign:'center', lineHeight:itemHeihght, opacity:0.8, paddingHorizontal: 10, } ]} >{emptyOptions.descText || '暂无数据'}</Text> </View> } public render(){ const { floor, currentFloor, setSelect, defaultSelected, maxLength, itemHeihght=50, ActiveTextStyle, normalTextStyle, pickerType, isLinkage, originData, emptyOptions, } = this.props const { nextData, initialScrollIndex, renderList, } = this.state const nextFloor = currentFloor 1 return ( <> <FlatList style={{flex:1}} ref={ref=>this.flatEl = ref} showsHorizontalScrollIndicator={false} showsVerticalScrollIndicator={false} keyExtractor={(item: object, index: number) => String(index)} renderItem={this.renderItem} viewabilityConfig={this.config} data={renderList} getItemLayout={this.getItemLayout} initialScrollIndex={initialScrollIndex} onMomentumScrollEnd={this._moveEnd} scrollEnabled={pickerType === 'click'?false:true} ListEmptyComponent={this.renderListEmptyComponent} /> { floor > nextFloor ? <PickerAlertViewItem ref={ref=>this.itemEL = ref} sourceList={nextData} floor={floor} setSelect={setSelect} currentFloor={nextFloor} defaultSelected={defaultSelected} maxLength={maxLength} itemHeihght={itemHeihght} ActiveTextStyle={ActiveTextStyle} normalTextStyle={normalTextStyle} pickerType={pickerType} isLinkage={isLinkage} originData={originData} emptyOptions={emptyOptions} />: null } </> ) } private _moveEnd=(e)=>{ const {itemHeihght} = this.props const { renderList } = this.state const contentOffset = e.nativeEvent.contentOffset.y; const mid = this.mid() const index = Math.round(contentOffset/itemHeihght) mid this.clickItem(renderList[index],index) }}export default WithHeadAndMethod(PickerAlertViewItem)

接上一版 多级联动组件;增加了非联动组件;完善了配置;优化了使用过程中的小问题;

  • 东北虎保护地有什么用(黑龙江饶河县再现东北虎)
  • 2024-11-22黑龙江饶河县再现东北虎黑龙江饶河县林草局又一次检测到了东北虎的身影,为了防止东北虎伤人事件发生,当地已经发出提醒,禁止市民入山,养殖户也要做好安全防范这只东北虎是被安装在野外的红外相机拍摄到的,从画面中可以看出,这只东北虎。
  • 神级签到系统所有的奖励都是神体(不朽王座签到系统)
  • 2024-11-22不朽王座签到系统说到签到系统,经常玩游戏的玩家应该不会陌生签到系统是给玩家们的福利,考验的是玩家的耐心一般累计签到次数越多,签到奖励越丰富现在我们就来看看《不朽王座》的签到系统吧!登录签到奖励每天的奖励都很清楚的写在。
  • 健康自我管理模型(走路跑步攒信用)
  • 2024-11-22走路跑步攒信用新华社上海10月5日电题:走路跑步“攒信用”健康管理成时尚新华社记者潘清长假里,上海白领周先生每天按照计划健走、跑步,通过“平安健康”App上传心率、血压等健康指标几天下来,周先生在HelloRunC。
  • 钢研纳克光谱仪代理品牌(读创公司问答钢研纳克)
  • 2024-11-22读创公司问答钢研纳克新华医疗、红宝丽、钢研纳克、索通发展、中金公司等公司近日在深交所互动易和上证e互动平台回答了部分投资者的提问新华医疗[600587]问:公司目前的主要收入来自境内,对境外市场今后有何规划,公司产品对比。
  • 世界上有几个玉龙(玉龙第三国的传说)
  • 2024-11-22玉龙第三国的传说疫情下的生活发生了一些糟糕的挫折,为了缓解压抑的心情,一个人驱车来到了云南大理、丽江和香格里拉,看到如此壮美的景色,心中的忧虑得到不少的缓解,完全沉浸在秀丽的风光之中在大理住了两个晚上,参观了宏伟的三。
  • 二月二全网最硬核龙抬头(二月二龙抬头银河掠夺者带你遨游星际)
  • 2024-11-22二月二龙抬头银河掠夺者带你遨游星际遨游太空一直都是每个人的梦想谷得旗下有一款叫做《银河掠夺者》的游戏,大片即视感的游戏画面,酷炫而迷人在这个游戏里,你可以操控自己的太空舰队,自由穿梭于星际之间对于视觉控来说,一款游戏的美术画面永远是他。
  • 直拍横打哪个手指发力(直拍横打想打好)
  • 2024-11-22直拍横打想打好点我观看视频版教学根据每个人的情况不同,正反手如果用一种握拍方式握得深,肯定有影响手指可以进行微调比如反手时两个手指对拍子控制更好正手时直板的灵活性调节球要用一个手指(中指),另外两个手指作为辅助更好。
  • 全民漂移为什么这么厉害(月收入过亿全民漂移买量)
  • 2024-11-22月收入过亿全民漂移买量文/爱写稿的罗斯基这两年超休闲游戏在全球市场爆发,国内的游戏开发者也在大量转型到这个方向2019年上半年,AppStore中国区出现如《消灭病毒》、《我飞刀玩的贼6》、《全民漂移》等多款国内开发者研发。
  • 康奈尔笔记法分类及转化 康奈尔笔记法使用最广泛最有效的学习笔记
  • 2024-11-22康奈尔笔记法分类及转化 康奈尔笔记法使用最广泛最有效的学习笔记康奈尔笔记——5R笔记法5R笔记法,又叫做康奈尔笔记法,是用产生这种笔记法的大学校名命名的这一方法几乎适用于一切讲授或阅读课,特别是对于听课笔记,5R笔记法应是最佳首选这种方法是记与学,思考与运用相结。
  • 机动车查封状态是什么意思(机动车查封状态的解释)
  • 2024-11-22机动车查封状态的解释分期付款车,拖欠银行款项,银行申请法院催款,法院给车管所发查封通知,禁止审验等一切业务是全款车,车主欠帐,债权人申请法院先将车辆保全查封,然后判决归属最后就是犯罪分子使用车辆犯罪或者用赃款购车,公安局。
  • 新三国周昌和周泰(美青年与帅大叔萌将风云周瑜周泰双周组合登场)
  • 2024-11-22美青年与帅大叔萌将风云周瑜周泰双周组合登场新概念微操卡牌手游《萌将风云》武将立绘补完计划渐入佳境,小月我也对目前的新版立绘甚是喜爱不过,看了这么多萌妹子的立绘,广大玩家老爷们是不是有些审美疲劳了呢?常言道美人如酒,而再好的酒也不能贪杯,今儿个。