Last active
February 28, 2018 15:21
-
-
Save kyryloz/f4ce1eaa1fc3cb3f3b9b9bf05c9b2cc3 to your computer and use it in GitHub Desktop.
NumberPicker react-native bridge (Android)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Wraps Android's `android.widget.NumberPicker`. | |
Supported 'Nothing' selection, which appears as first item in the NumberPicker. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// omitted | |
export const reactComponent = () => ( | |
<NumberPickerAndroid | |
style={styles.numberPicker} // set width and height | |
initialValues={{ | |
minValue: 1, | |
maxValue: 10, | |
initialValue: 3, | |
}} | |
onChange={value => {}} | |
wrapSelectorWheel={false} | |
/> | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// omitted | |
protected List<ReactPackage> getPackages() { | |
return Arrays.<ReactPackage>asList( | |
new MainReactPackage(), | |
new NumberPickerReactPackage()); | |
} | |
// omitted |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import PropTypes from 'prop-types' | |
import React from 'react' | |
import { | |
requireNativeComponent, | |
ViewPropTypes, | |
} from 'react-native' | |
import { | |
compose, | |
withHandlers, | |
} from 'recompose' | |
const componentInterface = { | |
name: 'NumberPickerAndroid', | |
propTypes: { | |
initialValues: PropTypes.shape({ | |
minValue: PropTypes.number, | |
maxValue: PropTypes.number, | |
initialValue: PropTypes.number, | |
}), | |
wrapSelectorWheel: PropTypes.bool, | |
onChange: PropTypes.func, | |
...ViewPropTypes, | |
}, | |
} | |
const NativeNumberPickerAndroid = requireNativeComponent('NumberPickerAndroid', componentInterface) | |
const handleValueChange = ({ onChange }) => event => onChange(event.nativeEvent.value) | |
export const NumberPickerAndroid = compose( | |
withHandlers({ | |
handleValueChange, | |
}), | |
)(props => ( | |
<NativeNumberPickerAndroid | |
{...props} | |
onChange={props.handleValueChange} | |
/> | |
)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.project.nativemodules.numberpicker; | |
import com.facebook.react.ReactPackage; | |
import com.facebook.react.bridge.NativeModule; | |
import com.facebook.react.bridge.ReactApplicationContext; | |
import com.facebook.react.uimanager.ViewManager; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.List; | |
public class NumberPickerReactPackage implements ReactPackage { | |
@Override | |
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { | |
List<ViewManager> viewManagers = new ArrayList<>(); | |
viewManagers.add(new NumberPickerViewManager()); | |
return viewManagers; | |
} | |
@Override | |
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { | |
return Collections.emptyList(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.project.nativemodules.numberpicker; | |
import android.widget.NumberPicker; | |
import com.facebook.react.bridge.Arguments; | |
import com.facebook.react.bridge.ReadableMap; | |
import com.facebook.react.bridge.WritableMap; | |
import com.facebook.react.common.MapBuilder; | |
import com.facebook.react.uimanager.SimpleViewManager; | |
import com.facebook.react.uimanager.ThemedReactContext; | |
import com.facebook.react.uimanager.UIManagerModule; | |
import com.facebook.react.uimanager.annotations.ReactProp; | |
import com.facebook.react.uimanager.events.Event; | |
import com.facebook.react.uimanager.events.RCTEventEmitter; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Map; | |
public class NumberPickerViewManager extends SimpleViewManager<ReactNumberPickerView> { | |
private static final String EVENT_NAME = "onChange"; | |
@Override | |
public String getName() { | |
return "NumberPickerAndroid"; | |
} | |
@Override | |
protected ReactNumberPickerView createViewInstance(ThemedReactContext reactContext) { | |
return new ReactNumberPickerView(reactContext); | |
} | |
@Override | |
public Map<String, Object> getExportedCustomBubblingEventTypeConstants() { | |
Map<String, Map<String, String>> eventBinding = MapBuilder.of( | |
"phasedRegistrationNames", | |
MapBuilder.of("bubbled", EVENT_NAME)); | |
return MapBuilder.<String, Object>builder() | |
.put(EVENT_NAME, eventBinding) | |
.build(); | |
} | |
public void addEventEmitters(final ThemedReactContext reactContext, ReactNumberPickerView view) { | |
view.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { | |
@Override | |
public void onValueChange(NumberPicker numberPicker, int oldValue, int newValue) { | |
final WritableMap eventData = Arguments.createMap(); | |
eventData.putInt("value", newValue == numberPicker.getMinValue() ? -1 : newValue); | |
reactContext.getNativeModule(UIManagerModule.class) | |
.getEventDispatcher() | |
.dispatchEvent(new Event(numberPicker.getId()) { | |
@Override | |
public String getEventName() { | |
return EVENT_NAME; | |
} | |
@Override | |
public void dispatch(RCTEventEmitter emitter) { | |
emitter.receiveEvent(getViewTag(), getEventName(), eventData); | |
} | |
}); | |
} | |
}); | |
} | |
@ReactProp(name = "initialValues") | |
public void setInitialValues(ReactNumberPickerView view, ReadableMap map) { | |
view.setMinValue(map.getInt("minValue") - 1); | |
view.setMaxValue(map.getInt("maxValue")); | |
view.setValue(map.getInt("initialValue")); | |
invalidateDisplayedValues(view); | |
} | |
@ReactProp(name = "wrapSelectorWheel") | |
public void setWrapSelectorWheel(ReactNumberPickerView view, boolean wrap) { | |
view.setWrapSelectorWheel(wrap); | |
} | |
private void invalidateDisplayedValues(ReactNumberPickerView view) { | |
List<String> displayedValues = new ArrayList<>(); | |
displayedValues.add("Nothing"); | |
for (int i = view.getMinValue() + 1; i <= view.getMaxValue(); i++) { | |
displayedValues.add(String.valueOf(i)); | |
} | |
view.setDisplayedValues(displayedValues.toArray(new String[0])); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.project.nativemodules.numberpicker; | |
import android.content.Context; | |
import android.widget.NumberPicker; | |
public class ReactNumberPickerView extends NumberPicker { | |
public ReactNumberPickerView(Context context) { | |
super(context); | |
setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment