I'm trying to understand how to properly pass options from the js side of react-native to the java side.
The react-native bridge uses ReadableMap to convert but as a Java noob I'm failing to understand how this works.
More specifically I don't understand:
Generally I would like to know how this works but I'll give the specific example I'm looking at to give some context.
A react-native package exposes a datetime picker.
The JS side has a showTimePicker method:
showTimePicker(date, callback) {
    date = date || new Date();
    console.log(this.props);
    debugger
    var options = {
        ...this.props,
        hour:date.getHours(),
        minute:date.getMinutes()
    };
    RCTDateTimePicker.showTimePicker(options, function (hour, minute) {
        date.setHours(hour);
        date.setMinutes(minute);
        callback(date);
    });
}
RCTDateTimePicker.showTimePicker is bridged to a Java method on the native side:
@ReactMethod
public void showTimePicker(ReadableMap options, Callback callback) {
    DialogFragment timePicker = new TimePicker(options, callback);
    timePicker.show(activity.getFragmentManager(), "timePicker");
}
which calls
public TimePicker(ReadableMap options, Callback callback) {
    final Calendar c = Calendar.getInstance();
    this.callback = callback;
    hour = options.hasKey("hour") ? options.getInt("hour") : c.get(Calendar.HOUR_OF_DAY);
    minute = options.hasKey("minute") ? options.getInt("minute") : c.get(Calendar.MINUTE);
}
which creates and instance of an Android TimePicker. My goal is to change the style of the Timepicker from watch to spinner.
There is a settable XML attribute android:timePickerMode="spinner" but I don't think I can pass an XML attribute through react-native can I?
I also found a suggestion in comments to pass defStyleAttr to do this, but I don't understand how.
First, see the list of Argument Types from the React Native document for Android Native Modules.
Argument Types
The following argument types are supported for methods annotated with @ReactMethod and they directly map to their JavaScript equivalents
- Boolean -> Bool
 - Integer -> Number
 - Double -> Number
 - Float -> Number
 - String -> String
 - Callback -> function
 - ReadableMap -> Object
 - ReadableArray -> Array
 
So, you can pass the extra field for timePickerMode as a String by updating the options that the JS side passes to include it.
var options = {
    ...this.props,
    hour:date.getHours(),
    minute:date.getMinutes(),
    timePickerMode:"spinner"
};
And then get that value from the ReadableMap in your custom TimePicker constructor.
String timePickerMode = options.hasKey("timePickerMode") ?
        options.getString("timePickerMode") : defaultTimePickerMode;
Now you have the value you wish to set. Unfortunately it does not appear that timePickerMode can be set programmatically. This SO question asks how to do it and @alanv (whose profile indicates they are a Software Engineer at Google) indicates that it is not possible at runtime.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With