lawnstarter / react-native-picker-select

🔽 A Picker component for React Native which emulates the native <select> interfaces for iOS and Android
https://npmjs.com/package/react-native-picker-select
MIT License
1.74k stars 499 forks source link

toggle not working in Android. #424

Closed hasn-ab closed 1 month ago

hasn-ab commented 3 years ago

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Use TouchableWithoutFeedback
  2. onPress I am toggling with this.pickerRef.current.togglePicker(false)

Expected behavior
Should open the picker

Screenshots
null

Additional details

Reproduction and/or code sample

<RNPickerSelect
          disabled={!editable}
          onValueChange={(v) => this.handleValueChange(v)}
          value={selectedValue}
          style={{ maxHeight: 0 }}
          ref={this.pickerRef}
          onUpArrow={this.onArrowUp}
          InputAccessoryView={this.InputAccessoryView}
          onDownArrow={this.onDownArrow}
          style={{
            chevronUp: {
              fontSize: 0,
              color: 'white',
            },
          }}
          items={values}>
          <View style={{ height: 0 }}></View>
        </RNPickerSelect>

        <TouchableWithoutFeedback
          onPress={() => {
            console.log('toogle');
            this.pickerRef.current.togglePicker(false);
          }}>
          <View style={[styles.inputContainer, style]}>
            {selectedValue.trim().length > 0 ? (
              <>
                <Text style={styles.labelStyle}>{placeholder}</Text>
                <Text style={styles.textInputStyle}>{label}</Text>
              </>
            ) : (
              <>
                <Text style={styles.labelStyle}>{placeholder}</Text>
              </>
            )}
          </View>
        </TouchableWithoutFeedback>
      </>
vladcorn commented 3 years ago

Also you can reproduce this bug with any onPress function

nakullondhe commented 3 years ago

I have the same issue, can anyone help?

NvIGA commented 3 years ago

I have the same issue

Lucas-Alvino commented 3 years ago

I have the same issue

bacarybruno commented 3 years ago

@hasnaina-entertainer this should work. As per this commit https://github.com/react-native-picker/picker/pull/258 (thanks @mateusz1913)

     <>
        <RNPickerSelect
          disabled={!editable}
          onValueChange={(v) => this.handleValueChange(v)}
          value={selectedValue}
          style={{ maxHeight: 0 }}
          pickerProps={{ ref: this.pickerRef }}
          ref={this.pickerRef}
          onUpArrow={this.onArrowUp}
          InputAccessoryView={this.InputAccessoryView}
          onDownArrow={this.onDownArrow}
          style={{
            chevronUp: {
              fontSize: 0,
              color: 'white',
            },
          }}
          items={values}>
          <View style={{ height: 0 }}></View>
        </RNPickerSelect>

        <TouchableWithoutFeedback onPress={() => { this.pickerRef.current.focus(); }}>
          {content}
        </TouchableWithoutFeedback>
     </>

Short answer (Android only)

<RNPickerSelect
   {...otherProps}
   pickerProps={{ ref: this.pickerRef }}
/>

and then

<TouchableWithoutFeedback onPress={this.pickerRef.current.focus}>
  {content}
</TouchableWithoutFeedback>

To make this work for Android & iOS you can do something like this

class PickerSelect extends React.Component {
  pickerRef = React.createRef()

  openPicker() {
    if (Platform.OS === 'android') {
      this.pickerRef.current.focus()
    } else {
      this.pickerRef.current.togglePicker(true)
    }
  }

  render() {
    const { onValueChange, items, value } = this.props
    return (
      <RNPickerSelect
        onValueChange={onValueChange}
        items={items}
        style={{ viewContainer: { height: 0 } }}
        ref={Platform.OS === 'ios' ? this.pickerRef : null}
        pickerProps={{ ref: Platform.OS === 'android' ? this.pickerRef : null }}
        value={value}
      />
    )
  }
}

and then

const pickerRef = useRef();

<PickerSelect
  ref={pickerRef}
  items={values}
/>

<TouchableWithoutFeedback onPress={pickerRef.current.openPicker}>
  {content}
</TouchableWithoutFeedback>
valeriashpiner commented 3 years ago

I got message for pickerProps={{ ref: this.pickerRef }}: Type '{ ref: React.MutableRefObject; }' is not assignable to type 'CustomPickerProps'. Also, I tried @bacarybruno solution and I always get Cannot read properly "openPicker" of null.

romanmatus commented 1 year ago

Hello, this problem still presist on android devices, or is it only for me ?

const handlePickerToggle = () => { if (dropDownRef.current) { dropDownRef.current.togglePicker();
} };

      <TouchableOpacity className="bg-blue-200" onPress={handlePickerToggle}>
      <View className="h-full flex-row items-center">
        <Image
          className="h-6 w-6 mr-2 ml-2"
          source={getImageSource(nationalPrefix)}
        />
        <DropDown 
          ref={dropDownRef}
          fixAndroidTouchableBug={true}
          useNativeAndroidPickerStyle={false}
          placeholder={{
            label: ".",
            value: ".",
            inputLabel: ".",
          }}
          onValueChange={(value) => {
            setNationalPrefix(value);
            handleValueChange();
          }}
          style={pickerStyle}
          items={[
            { label: "a", value: "+4", inputLabel: "+4" },
            { label: "b", value: "+3", inputLabel: "+3" },
          ]}

        />

        <Feather
          className="ml-2 mr-2"
          name={"chevron-down"}
          size={20}
          color="#899295"
        />
      </View>
    </TouchableOpacity>

it works perfectly on ios, but on android it is working only if you press inside red square.

image

any advice please?

lfkwtz commented 1 month ago

22

Ke0x commented 4 weeks ago

The solution above doesnt work for me, No matter what i tried i cant open the Picker with the focus function, i dont have any error.

vahidd commented 3 days ago

@Ke0x

pickerRef.current.togglePicker(true);