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