最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - how does the ReadableMap interface in React-native convert JS to JAVA? - Stack Overflow

programmeradmin0浏览0评论

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:

  • how the actual conversion works?
  • how to tell what type/format the downstream Java code wants?
  • how to properly use ReadableMap to do this?

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.

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:

  • how the actual conversion works?
  • how to tell what type/format the downstream Java code wants?
  • how to properly use ReadableMap to do this?

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.

Share Improve this question edited May 23, 2017 at 12:00 CommunityBot 11 silver badge asked Jul 21, 2016 at 7:37 funkyeahfunkyeah 3,1846 gold badges32 silver badges48 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 15 +50

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.

发布评论

评论列表(0)

  1. 暂无评论