From a62a685b1412d1c0eda036262af2ee97338aac40 Mon Sep 17 00:00:00 2001 From: Oleksandr Melnykov Date: Mon, 11 Nov 2019 12:31:06 -0800 Subject: [PATCH] Add setNativeSelectedPosition command to ReactPickerManager Summary: Fabric doesn't support setNativeProps, so we have to use commands instead to set the value of the native component. Changelog: [Android] [Added] - Add setNativeSelectedPosition command to ReactPickerManager Reviewed By: mdvacca Differential Revision: D18007791 fbshipit-source-id: dfa26792205189a336ab43b1c51f43f8f57c8e72 --- .../AndroidDialogPickerNativeComponent.js | 22 +++++++++++++++---- .../AndroidDropdownPickerNativeComponent.js | 22 +++++++++++++++---- .../react/views/picker/ReactPicker.java | 9 ++++++++ .../views/picker/ReactPickerManager.java | 13 +++++++++++ 4 files changed, 58 insertions(+), 8 deletions(-) diff --git a/Libraries/Components/Picker/AndroidDialogPickerNativeComponent.js b/Libraries/Components/Picker/AndroidDialogPickerNativeComponent.js index 8c74288f775..574d9773362 100644 --- a/Libraries/Components/Picker/AndroidDialogPickerNativeComponent.js +++ b/Libraries/Components/Picker/AndroidDialogPickerNativeComponent.js @@ -10,6 +10,9 @@ 'use strict'; +import * as React from 'react'; + +import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands'; import {requireNativeComponent} from 'react-native'; import type { @@ -46,8 +49,19 @@ type NativeProps = $ReadOnly<{| onSelect?: DirectEventHandler, |}>; -const AndroidDialogPickerNativeComponent: HostComponent = requireNativeComponent( - 'AndroidDialogPicker', -); +type NativeType = HostComponent; -module.exports = AndroidDialogPickerNativeComponent; +interface NativeCommands { + +setNativeSelectedPosition: ( + viewRef: React.ElementRef, + index: number, + ) => void; +} + +export const Commands: NativeCommands = codegenNativeCommands({ + supportedCommands: ['setNativeSelectedPosition'], +}); + +export default (requireNativeComponent( + 'AndroidDialogPicker', +): NativeType); diff --git a/Libraries/Components/Picker/AndroidDropdownPickerNativeComponent.js b/Libraries/Components/Picker/AndroidDropdownPickerNativeComponent.js index 82f455c2fb5..7c637ef4e6b 100644 --- a/Libraries/Components/Picker/AndroidDropdownPickerNativeComponent.js +++ b/Libraries/Components/Picker/AndroidDropdownPickerNativeComponent.js @@ -10,6 +10,9 @@ 'use strict'; +import * as React from 'react'; + +import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands'; import {requireNativeComponent} from 'react-native'; import type { @@ -46,8 +49,19 @@ type NativeProps = $ReadOnly<{| onSelect?: DirectEventHandler, |}>; -const AndroidDropdownPickerNativeComponent: HostComponent = requireNativeComponent( - 'AndroidDropdownPicker', -); +type NativeType = HostComponent; -module.exports = AndroidDropdownPickerNativeComponent; +interface NativeCommands { + +setNativeSelectedPosition: ( + viewRef: React.ElementRef, + index: number, + ) => void; +} + +export const Commands: NativeCommands = codegenNativeCommands({ + supportedCommands: ['setNativeSelectedPosition'], +}); + +export default (requireNativeComponent( + 'AndroidDropdownPicker', +): NativeType); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPicker.java b/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPicker.java index 93024d344ab..fd6edeb7e2b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPicker.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPicker.java @@ -123,6 +123,15 @@ public class ReactPicker extends AppCompatSpinner { mStagedSelection = selection; } + /** Will set the "selection" value immediately as opposed to {@link #setStagedSelection(int)} */ + /* package */ void setImmediateSelection(int selection) { + if (selection != getSelectedItemPosition()) { + setOnItemSelectedListener(null); + setSelection(selection, false); + setOnItemSelectedListener(mItemSelectedListener); + } + } + /* package */ void setStagedPrimaryTextColor(@Nullable Integer primaryColor) { mStagedPrimaryTextColor = primaryColor; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java index 0a35a57f41a..b03783ca3fe 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java @@ -8,6 +8,7 @@ package com.facebook.react.views.picker; import android.widget.Spinner; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.uimanager.SimpleViewManager; @@ -66,6 +67,18 @@ public abstract class ReactPickerManager extends SimpleViewManager picker, reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher())); } + @Override + public void receiveCommand( + @NonNull ReactPicker view, String commandId, @Nullable ReadableArray args) { + switch (commandId) { + case "setNativeSelectedPosition": + if (args != null) { + view.setImmediateSelection(args.getInt(0)); + break; + } + } + } + private static class PickerEventEmitter implements ReactPicker.OnSelectListener { private final ReactPicker mReactPicker;