Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何开发一个react-native android组件 #1

Open
shexiaoheng opened this issue Dec 3, 2015 · 2 comments
Open

如何开发一个react-native android组件 #1

shexiaoheng opened this issue Dec 3, 2015 · 2 comments

Comments

@shexiaoheng
Copy link

首先按照官网文档的步骤来做:
1. Create the ViewManager subclass
2. Implement method createViewInstance
3. Expose view property setters using @ReactProp (or @ReactPropGroup) annotation
4. Register the ViewManager
5. Implement the JavaScript module
在native组件只有设置属性的时很按照上面的来做很容易就搞定了,但是实际开发中既然是组件,肯定会有相应的事件监听处理和外部调用的方法。

事件的处理:

对于Event的处理也有官方文档 ,不过对应的.JS文件并不健全,可以参考我写过的react-native-wheel的实现:
WheelViewManager.java:

@ReactProp(name = "onItemChange", defaultBoolean = true)
    public void setOnItemChange(final LoopView view, Boolean value) {
        view.setListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(int index) {
                WritableMap event = Arguments.createMap();
                event.putInt("index", index);
                ReactContext reactContext = (ReactContext) view.getContext();
                reactContext.getJSModule(RCTEventEmitter.class)
                        .receiveEvent(view.getId(), "topChange", event);
            }
        });
    }

index.js

var iface = {
    name: 'RCTWheelView',
    propTypes: {
        onItemChange: PropTypes.func,
        values: PropTypes.array,
        isLoop: PropTypes.bool,
        selectedIndex: PropTypes.number,
        textSize: PropTypes.number,
    },
};

var MyWheelView = React.createClass({

    handleOnChange(event){
        if(this.props.onItemChange){
            this.props.onItemChange(event.nativeEvent.index);
        }
    },
    render(){
        return <NativeWheelView {...this.props} onChange = {this.handleOnChange} />;
    }
});
方法的处理:

React-Native的官方文档并没有对应的文档说明,找了好几天都没有找到相应的处理,最终无奈在react-native的github提交了一个issues,然后在@brentvatne的帮助下得以解决
参考以下内容:
ReactViewPagerManager.java:

  @Override
  public Map<String,Integer> getCommandsMap() {
    return MapBuilder.of(
        "setPage",
        COMMAND_SET_PAGE,
        "setPageWithoutAnimation",
        COMMAND_SET_PAGE_WITHOUT_ANIMATION);
  }

  @Override
  public void receiveCommand(
      ReactViewPager viewPager,
      int commandType,
      @Nullable ReadableArray args) {
    Assertions.assertNotNull(viewPager);
    Assertions.assertNotNull(args);
    switch (commandType) {
      case COMMAND_SET_PAGE: {
        viewPager.setCurrentItemFromJs(args.getInt(0), true);
        return;
      }
      case COMMAND_SET_PAGE_WITHOUT_ANIMATION: {
        viewPager.setCurrentItemFromJs(args.getInt(0), false);
        return;
      }
      default:
        throw new IllegalArgumentException(String.format(
            "Unsupported command %d received by %s.",
            commandType,
            getClass().getSimpleName()));
    }
  }

ViewPagerAndroid.android.js:

 /**
   * A helper function to scroll to a specific page in the ViewPager.
   * The transition between pages will be animated.
   */
  setPage: function(selectedPage: number) {
    UIManager.dispatchViewManagerCommand(
      React.findNodeHandle(this),
      UIManager.AndroidViewPager.Commands.setPage,
      [selectedPage],
    );
  },

  /**
   * A helper function to scroll to a specific page in the ViewPager.
   * The transition between pages will be *not* be animated.
   */
  setPageWithoutAnimation: function(selectedPage: number) {
    UIManager.dispatchViewManagerCommand(
      React.findNodeHandle(this),
      UIManager.AndroidViewPager.Commands.setPageWithoutAnimation,
      [selectedPage],
    );
  },

最后就是就像@brentvatne说的 “This isn't the best place to ask this kind of question, as the comment above suggests, you should try StackOverflow.” 提问问题最好去StackOverflow ,再次感谢@brentvatne的回答。

@brentvatne
Copy link

💃

@shexiaoheng
Copy link
Author

对于方法的处理,我也写了一个例子

WheelViewManager.java

 @Override
    public Map<String,Integer> getCommandsMap() {
        return MapBuilder.of(
                "previous",
                COMMAND_PREVIOUS,
                "next",
                COMMAND_NEXT);
    }

    @Override
    public void receiveCommand(LoopView root, int commandId, ReadableArray args) {
        switch (commandId) {
            case COMMAND_PREVIOUS: {
                root.previous();
                return;
            }
            case COMMAND_NEXT: {
                root.next();
                return;
            }
            default:
                throw new IllegalArgumentException(String.format(
                        "Unsupported command %d received by %s.",
                        commandId,
                        getClass().getSimpleName()));
        }
    }

index.js

previous: function(){
        UIManager.dispatchViewManagerCommand(
            React.findNodeHandle(this.refs.wheel),
            UIManager.RCTWheelView.Commands.previous,
            null,
        );
    },
    next: function(){
        UIManager.dispatchViewManagerCommand(
            React.findNodeHandle(this.refs.wheel),
            UIManager.RCTWheelView.Commands.next,
            null,
        );
    },

使用方法

index.android.js

var AwesomeProject = React.createClass({
  previous(){
    this.refs.wheel.previous();
  },
  next(){
    this.refs.wheel.next();
  },
  finish(){
    ToastAndroid.show('select item : ' + wheelData[currentIndex] ,ToastAndroid.LONG);
  },
  onItemChange(index){
    currentIndex = index;
  },
  render: function() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome} onPress={this.previous} >
          上一个
        </Text>
        <Text style={styles.instructions} onPress={this.next} >
          下一个
        </Text>
        <Text style={styles.instructions} onPress={this.finish} >
          完成
        </Text>
        <WheelView
          style={styles.wheelview}
          onItemChange={this.onItemChange}
          values={wheelData}
          isLoop={false}
          selectedIndex={0}
          textSize={20}
          ref='wheel'
        />
      </View>
    );
  }
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants