react-native多功能模态弹框选择

看着那些选择组件,不能满足开发项目的需求,还是自己编写一个
自定义的模态框选择组件

功能说明
同一个组件实现如下功能
0、出现动画效果
1、多选:可以实现多选的功能
2、单选:可以实现单项选择
3、存在默认值情况处理

**
 * 模态选择框
 * 
 *  props:
 *      data:  [{id:1,display: '111111',}],//数据格式 id 和display描述
 *      mult:  true|false 是否多选 
 *      dataKey:{id:"_id",display:"text"}  //自定义索引key
 *      search  是否可以搜索/本地过滤 默认true
 *      title   提示标题  默认 请选择  
 *      defaultChecked;  //  1 | "1" | {id:1} | {index:1} | [...]
 *      onChange  (item)=>     
 *      //个性化定制  每一个item点击时调用
 *      //style={UISelectModal.style.borderRadius} 
        //rootStyle={{width:100,alignSelf: 'flex-end',}}
 *      activeColor   选中颜色
 *      
 *      RenderItem:(item,isActive)=>  //自定义 item样式  
 *     
 *   ref ----绑定ref  用来获取选中的值  this.refs.定义的ref.getVlue();
 *  func
 *     getValue:  return [] | {}
 */
import React,{Component} from 'react';

import {
    Animated,
    View,
    TextInput,
    Image,
    TouchableOpacity,
    StyleSheet,
    Text,
    Button,
    ImageBackground,
    Modal,
    FlatList,
    Platform,
    ScrollView,
    TouchableHighlight} from 'react-native';

export default class UISelectModal extends Component{
    constructor(props){
        super(props);
        this.state={
            searchData:null,
            show:false,
            fadeAnim: new Animated.Value(100),
            checkedState:{}, //记录选项选中状态
            data:this.props.data || [],
        }
    }
    componentDidMount(){
        this.initDefaultChecked(this.props.defaultChecked);
    }
    /**初始化默认选中 */
    isInitDefaultChecked=false;
    initDefaultChecked=(defaultChecked,target=0)=>{
       if(this.isInitDefaultChecked){
          return false;
       }

       let type = typeof(defaultChecked);
       if(type === "string" || type === "number"){
           this.setCheckedState(defaultChecked,true);
       }else if(defaultChecked instanceof Array){
           for(let i=0;i{
        return this.state.checkedState;
    }
    setCheckedState=(key,state)=>{
       let c = this.getCheckedStateConfig();
       c[key] = state;
    }
    getCheckedState=(key=null)=>{
       let c = this.getCheckedStateConfig();
       if(key){
           return !!c[key];
       }
       let actives = [];
       for(let key in c){
           let ac = !!c[key];
           if(ac)actives.push(key);
       }
       return actives;
    }
    clearAllCheckedState=()=>{
       this.state.checkedState = {};
    }
    switchCheckedState=(key)=>{
       let old = this.getCheckedState(key);
       let active = !old;
       this.setCheckedState(key,active);    
       return active;  
    }
    updateCheckedState=()=>{
        this.setState({checkedState:this.getCheckedStateConfig()});
    }
    getActiveItem=()=>{
        let cs = this.getCheckedState();
        let ds = this.state.data;
        let activeItems = [];

        for(let i=0;ithis.getItemID(item) == activeID);
           if(activeIndex<=-1)continue;
           let activeItem = ds[activeIndex];
           activeItems.push(activeItem);
        }
        return activeItems;
    }
    getItemID=(item)=>{
        const key = this.props.dataKey||{};
        return item[key["id"]];
    }
    getItemDiaplay=(item)=>{
        const key = this.props.dataKey||{};
        return item[key["display"]];
    }

    getValue(){
        let activeItem = this.getActiveItem();
        let mult = this.props.mult;
        if(!mult){
            return activeItem[0];
        }
        return activeItem;
    }
    
    componentWillReceiveProps(nextProps){
        let nextData = nextProps.data;
        this.setState(({data})=>{
           return {data:nextData};
        },()=>{
            this.initDefaultChecked(nextProps.defaultChecked);
        });
    }
    switch=(state = null)=>{
        let isShow = !this.state.show;
        this.setState({show:isShow,searchData:null},()=>{
               this.state.fadeAnim.setValue(0);
               this.animated = Animated.spring(                 
                       this.state.fadeAnim,           
                       {
                           toValue:100,      
                           duration:300, 
                       }
               ).start();
        })
    }
    componentWillUnmount(){
         if(this.state.show){
            this.setState({show:false});
         }
    }

    getTitleDisplay(){
      
         let activeItems = this.getActiveItem();
         let names = activeItems.map((item)=>this.getItemDiaplay(item));
         return names.length>0?
                
                    {names.join(",")}
                :
                
                    {this.props.title}
                
       
    }
    search(e) {
       if(!e){
           this.setState({searchData:null});
           return;
       };
       let list = this.state.data;
       const key = this.props.dataKey||{};
       let newList = list.filter((item)=>{
           return this.getItemDiaplay(item).indexOf(e)>-1;
       });
       this.setState({searchData:newList});
   }
 
   checkItem=(item)=>{
      let mult = this.props.mult;

      let id = this.getItemID(item);
      let active = this.getCheckedState(id);
      let nextActive = !active; 

      if(nextActive){
         let checkedStates =  this.getCheckedState();
         if(checkedStates && checkedStates.length){
            if(typeof mult === "number"){
                if(checkedStates.length>=mult){
                    return alert("最多选择"+mult+"项");
                }
            }else if(!mult){
                this.clearAllCheckedState();
            }
         }
      }

      this.setCheckedState(id,nextActive);
      this.updateCheckedState();
      
      
      let onChange = this.props.onChange;
      if(typeof(onChange) === "function"){
         onChange(item,this.getActiveItem());
      }

      //不是多选选择完马上关闭
      if(!mult)this.switch();
   }
    render() {
       const spinOpacity = this.state.fadeAnim.interpolate({
           inputRange: [0, 100],
           outputRange: [0,1]
       });
       const spinRotate = this.state.fadeAnim.interpolate({
           inputRange: [0, 100],
           outputRange: this.state.show?["0deg","180deg"]:['180deg', '0deg']
       });
        const spinTop = this.state.fadeAnim.interpolate({
            inputRange: [0, 100],
            outputRange:[140,0]
        });
       const key = this.props.dataKey||{};
       let dataList = this.state.searchData || this.state.data || [];
       let isSearch = this.props.search;
       let RenderItem = this.props.RenderItem;

       let activeColor = this.props.activeColor;
      return (
         
                  
                       
                           { this.getTitleDisplay()}
                       
                       
                          
                        
                      
                  
               {
                   (this.state.show) && 
                   
                       

                       
                                    
                                         {this.props.title}
                                    
                                   
                                    {
                                        dataList.length<=0?
                                        
                                              {(this.state.searchData && this.state.searchData.length<1)?"没有搜索到数据":"暂无数据"}
                                        :
                                        
                                            
                                                
                                                     {
                                                         dataList.map((item,index)=>{
                                                            let id = this.getItemID(item);
                                                            let display = this.getItemDiaplay(item);
                                                            let active = this.getCheckedState(id);
                                                            return(
                                                                typeof(RenderItem) === "function"?
                                                                       this.checkItem(item)}>
                                                                          {
                                                                            RenderItem(item,active)
                                                                          }
                                                                       
                                                                       :
                                                                        this.checkItem(item)}>
                                                                            
                                                                                    
                                                                                    
                                                                                    {
                                                                                        
                                                                                            {display}
                                                                                        
                                                                                    }
                                                                              
                                                                          
                                                            );
                                                        })
                                                     }
                                                
                                            
                                            
                                   }

                                   {
                                      (dataList.length>5 && isSearch) &&
                                       
                                            this.search(e)}
                                                />
                                        
                                   } 
                       

                      

                       


                 
               }
         
      )
    }
}

react-native多功能模态弹框选择_第1张图片        react-native多功能模态弹框选择_第2张图片      

 

在此插件基础上扩展---复选框
{
		//data {id:1,display:'选项1'}
		//获取选择的内容
	    this.refs.selects.getValue();
	
	}}
	defaultChecked={{index:0}} 
	rootStyle={{marginHorizontal:10,}}
	style={{margin:4}} 
	mult={true} />

 

/**
 * 单选复选框
 * RenderItem 
 */
export class UISelect extends UISelectModal{
    static defaultProps = {
        dataKey:{id:"id",display:"display"},
        mult:false,
        activeColor:themeConfig.mainBgColor,
        rootStyle:{},
    }
    styles = StyleSheet.create({
        root:{
            flexDirection:"row",
            flexWrap:"wrap"
        },
        item:{
            paddingHorizontal:10,
            paddingVertical:4,
            borderColor:"#f7f7f7",
            borderWidth:1,
            borderRadius:20,
            margin:5,
        }
    });
    render(){
        let data = this.state.data;
        let RenderItem = this.props.RenderItem;
        const styles = this.styles;
        const activeColor = this.props.activeColor;
        return (
             
                {
                    (data && data.length)? 
                     data.map((item,index)=>{
                        let id = this.getItemID(item);
                        let display = this.getItemDiaplay(item);
                        let active = this.getCheckedState(id);
                        let color = (active?activeColor:"#666666");
                        return(
                            typeof(RenderItem) === "function"?
                            this.checkItem(item)}>
                               {
                                 RenderItem(item,active)
                               }
                            
                            :
                            this.checkItem(item)}>
                                {display}
                                                        
                        );
                     }):false
                }
             
        )
    };
}








 

react-native多功能模态弹框选择_第3张图片

 

 

 

 

 

你可能感兴趣的:(笔记,react-native)