sohobloo / react-native-modal-dropdown

A react-native dropdown/picker/selector component for both Android & iOS.
MIT License
1.19k stars 477 forks source link

List view is deprecated in react native 0.60 #217

Open ibtesamlatif2997 opened 5 years ago

ibtesamlatif2997 commented 5 years ago

List VIew is deprecated in react native 0.60. So the quick fix is to use deprecated-react-native-listview

Need to add import ListView from "deprecated-react-native-listview";

instead of import ListView from from 'react-native';

uguraktas commented 5 years ago

Okey,so in node_modules/react-native-modal-dropdown/component/ModalDropdown.js

Remove import ListView from from 'react-native';

Add import ListView from "deprecated-react-native-listview";

soumyamishra89 commented 5 years ago

is anyone working on it to fix this?

alexcrist commented 5 years ago

Just opened a PR: https://github.com/sohobloo/react-native-modal-dropdown/pull/225

ghost commented 5 years ago

change list view to flat list:

import React, { Component } from "react";

import { StyleSheet, Dimensions, View, Text, FlatList, TouchableWithoutFeedback, TouchableNativeFeedback, TouchableOpacity, TouchableHighlight, Modal, ActivityIndicator } from "react-native";

import PropTypes from "prop-types"; import ListView from "deprecated-react-native-listview"; const TOUCHABLE_ELEMENTS = [ "TouchableHighlight", "TouchableOpacity", "TouchableWithoutFeedback", "TouchableNativeFeedback" ];

export default class ModalDropdown extends Component { static propTypes = { disabled: PropTypes.bool, scrollEnabled: PropTypes.bool, defaultIndex: PropTypes.number, defaultValue: PropTypes.string, options: PropTypes.array,

accessible: PropTypes.bool,
animated: PropTypes.bool,
showsVerticalScrollIndicator: PropTypes.bool,
keyboardShouldPersistTaps: PropTypes.string,

style: PropTypes.oneOfType([
  PropTypes.number,
  PropTypes.object,
  PropTypes.array
]),
textStyle: PropTypes.oneOfType([
  PropTypes.number,
  PropTypes.object,
  PropTypes.array
]),
dropdownStyle: PropTypes.oneOfType([
  PropTypes.number,
  PropTypes.object,
  PropTypes.array
]),
dropdownTextStyle: PropTypes.oneOfType([
  PropTypes.number,
  PropTypes.object,
  PropTypes.array
]),
dropdownTextHighlightStyle: PropTypes.oneOfType([
  PropTypes.number,
  PropTypes.object,
  PropTypes.array
]),

adjustFrame: PropTypes.func,
renderRow: PropTypes.func,
renderSeparator: PropTypes.func,
renderButtonText: PropTypes.func,

onDropdownWillShow: PropTypes.func,
onDropdownWillHide: PropTypes.func,
onSelect: PropTypes.func

};

static defaultProps = { disabled: false, scrollEnabled: true, defaultIndex: -1, defaultValue: "Please select...", options: null, animated: true, showsVerticalScrollIndicator: true, keyboardShouldPersistTaps: "never" };

constructor(props) { super(props);

this._button = null;
this._buttonFrame = null;
this._nextValue = null;
this._nextIndex = null;

this.state = {
  accessible: !!props.accessible,
  loading: !props.options,
  showDropdown: false,
  buttonText: props.defaultValue,
  selectedIndex: props.defaultIndex
};

}

componentWillReceiveProps(nextProps) { let { buttonText, selectedIndex } = this.state; const { defaultIndex, defaultValue, options } = nextProps; buttonText = this._nextValue == null ? buttonText : this._nextValue; selectedIndex = this._nextIndex == null ? selectedIndex : this._nextIndex; if (selectedIndex < 0) { selectedIndex = defaultIndex; if (selectedIndex < 0) { buttonText = defaultValue; } } this._nextValue = null; this._nextIndex = null;

this.setState({
  loading: !options,
  buttonText,
  selectedIndex
});

}

render() { return ( <View {...this.props}> {this._renderButton()} {this._renderModal()} ); }

_updatePosition(callback) { if (this._button && this._button.measure) { this._button.measure((fx, fy, width, height, px, py) => { this._buttonFrame = { x: px, y: py, w: width, h: height }; callback && callback(); }); } }

show() { this._updatePosition(() => { this.setState({ showDropdown: true }); }); }

hide() { this.setState({ showDropdown: false }); }

select(idx) { const { defaultValue, options, defaultIndex, renderButtonText } = this.props;

let value = defaultValue;
if (idx == null || !options || idx >= options.length) {
  idx = defaultIndex;
}

if (idx >= 0) {
  value = renderButtonText
    ? renderButtonText(options[idx])
    : options[idx].toString();
}

this._nextValue = value;
this._nextIndex = idx;

this.setState({
  buttonText: value,
  selectedIndex: idx
});

}

_renderButton() { const { disabled, accessible, children, textStyle } = this.props; const { buttonText } = this.state;

return (
  <TouchableOpacity
    ref={button => (this._button = button)}
    disabled={disabled}
    accessible={accessible}
    onPress={this._onButtonPress}
  >
    {children || (
      <View style={styles.button}>
        <Text style={[styles.buttonText, textStyle]} numberOfLines={1}>
          {buttonText}
        </Text>
      </View>
    )}
  </TouchableOpacity>
);

}

_onButtonPress = () => { const { onDropdownWillShow } = this.props; if (!onDropdownWillShow || onDropdownWillShow() !== false) { this.show(); } };

_renderModal() { const { animated, accessible, dropdownStyle } = this.props; const { showDropdown, loading } = this.state; if (showDropdown && this._buttonFrame) { const frameStyle = this._calcPosition(); const animationType = animated ? "fade" : "none"; return ( <Modal animationType={animationType} visible={true} transparent={true} onRequestClose={this._onRequestClose} supportedOrientations={[ "portrait", "portrait-upside-down", "landscape", "landscape-left", "landscape-right" ]}

<TouchableWithoutFeedback accessible={accessible} disabled={!showDropdown} onPress={this._onModalPress}

{loading ? this._renderLoading() : this._renderDropdown()}

); } }

_calcPosition() { const { dropdownStyle, style, adjustFrame } = this.props;

const dimensions = Dimensions.get("window");
const windowWidth = dimensions.width;
const windowHeight = dimensions.height;

const dropdownHeight =
  (dropdownStyle && StyleSheet.flatten(dropdownStyle).height) ||
  StyleSheet.flatten(styles.dropdown).height;

const bottomSpace =
  windowHeight - this._buttonFrame.y - this._buttonFrame.h;
const rightSpace = windowWidth - this._buttonFrame.x;
const showInBottom =
  bottomSpace >= dropdownHeight || bottomSpace >= this._buttonFrame.y;
const showInLeft = rightSpace >= this._buttonFrame.x;

const positionStyle = {
  height: dropdownHeight,
  top: showInBottom
    ? this._buttonFrame.y + this._buttonFrame.h
    : Math.max(0, this._buttonFrame.y - dropdownHeight)
};

if (showInLeft) {
  positionStyle.left = this._buttonFrame.x;
} else {
  const dropdownWidth =
    (dropdownStyle && StyleSheet.flatten(dropdownStyle).width) ||
    (style && StyleSheet.flatten(style).width) ||
    -1;
  if (dropdownWidth !== -1) {
    positionStyle.width = dropdownWidth;
  }
  positionStyle.right = rightSpace - this._buttonFrame.w;
}

return adjustFrame ? adjustFrame(positionStyle) : positionStyle;

}

_onRequestClose = () => { const { onDropdownWillHide } = this.props; if (!onDropdownWillHide || onDropdownWillHide() !== false) { this.hide(); } };

_onModalPress = () => { const { onDropdownWillHide } = this.props; if (!onDropdownWillHide || onDropdownWillHide() !== false) { this.hide(); } };

_renderLoading() { return ; }

renderDropdown() { const { options, showsVerticalScrollIndicator } = this.props; return ( <FlatList data={options} style={styles.list} renderItem={this.renderItem} showsVerticalScrollIndicator={showsVerticalScrollIndicator} /> ); } renderItem = ({ item, index, separators }) => { const { renderRow, dropdownTextStyle, dropdownTextHighlightStyle, accessible } = this.props; const { selectedIndex } = this.state; const key = `row${index}`; const highlighted = index == selectedIndex; const row = !renderRow ? ( <Text style={[ styles.rowText, dropdownTextStyle, highlighted && styles.highlightedRowText, highlighted && dropdownTextHighlightStyle ]}

{item} ) : ( renderRow(item, index, highlighted) ); const preservedProps = { key, accessible, onPress: () => this._onRowPress(item, index) }; if (TOUCHABLE_ELEMENTS.find(name => name == row.type.displayName)) { const props = { ...row.props }; props.key = preservedProps.key; props.onPress = preservedProps.onPress; const { children } = row.props; switch (row.type.displayName) { case "TouchableHighlight": { return <TouchableHighlight {...props}>{children}; } case "TouchableOpacity": { return <TouchableOpacity {...props}>{children}; } case "TouchableWithoutFeedback": { return ( <TouchableWithoutFeedback {...props}> {children} ); } case "TouchableNativeFeedback": { return ( <TouchableNativeFeedback {...props}> {children} ); } default: break; } } return <TouchableHighlight {...preservedProps}>{row}; };

_onRowPress(item, index) { const { onSelect, renderButtonText, onDropdownWillHide } = this.props; if (!onSelect || onSelect(index, item) !== false) { const value = (renderButtonText && renderButtonText(item)) || item.toString(); this._nextValue = value; this._nextIndex = index; this.setState({ buttonText: value, selectedIndex: index }); } if (!onDropdownWillHide || onDropdownWillHide() !== false) { this.setState({ showDropdown: false }); } }

renderSeparator = (sectionID, rowID, adjacentRowHighlighted) => { const key = `spr${rowID}`; return ; }; }

const styles = StyleSheet.create({ button: { justifyContent: "center" }, buttonText: { fontSize: 12 }, modal: { flexGrow: 1 }, dropdown: { position: "absolute", height: (33 + StyleSheet.hairlineWidth) * 5, borderWidth: StyleSheet.hairlineWidth, borderColor: "lightgray", borderRadius: 2, backgroundColor: "white", justifyContent: "center" }, loading: { alignSelf: "center" }, list: { //flexGrow: 1, }, rowText: { paddingHorizontal: 6, paddingVertical: 10, fontSize: 11, color: "gray", backgroundColor: "white", textAlignVertical: "center" }, highlightedRowText: { color: "black" }, separator: { height: StyleSheet.hairlineWidth, backgroundColor: "lightgray" } });

riyga25 commented 5 years ago

you can use my fork

xstable commented 5 years ago

@riyga25 did you open a PR for this? I would love to see your changes merged into the next Version. Thanks for your effort.

But I even found a Bug at your implementation. If I click on an entry in the Item-List I got "highlightRow" is not a function. To fix this change Line 392 from: highlightRow(rowID); to highlightRow.highlight(rowID); And btw. it seems that key's for Items are missing (got an yellow-alert-box for this.

riyga25 commented 5 years ago

@xstable No, I did't, I think PR will not be accepted, because the project seems dead. Thanks! I fixed it, but I didn't check) I hope it's work

xstable commented 5 years ago

So please give them a change to merge anyway. Hopefully @sohobloo will merge it one day.

ryndm commented 3 years ago

Okey,so in node_modules/react-native-modal-dropdown/component/ModalDropdown.js

Remove import ListView from from 'react-native';

Add import ListView from "deprecated-react-native-listview";

Thanks man, this worked out for me