原生UI组件
React-Native之Android:封装原生UI组件
与自定义module差不多,module继承‘ReactContextBaseJavaModule’
view继承 SimpleViewManager
rn版本0.38
使用android textView
1、实现SimpleViewManager ViewManager的子类
package react.view;
import android.graphics.Color;
import android.widget.TextView;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.annotations.ReactProp;
/**
* Created by Administrator on 2016/12/7.
*/
public class MyViewManager extends SimpleViewManager<TextView> {
@Override
public String getName() {
return "MyTextView";
}
@Override
protected TextView createViewInstance(ThemedReactContext reactContext) {
return new TextView(reactContext.getBaseContext());
}
private void log(String str) {
// Log.d("MyViewManager", str);
}
@ReactProp(name = "text")
public void setText(TextView view, String text) {
log("setText ->" + view.toString() + " " + text);
view.setText(text);
}
@ReactProp(name = ViewProps.BACKGROUND_COLOR, defaultInt = 0x000000)
public void setBackgroudColor(TextView view, int color) {
view.setBackgroundColor(color);
}
@ReactProp(name = ViewProps.FONT_SIZE, defaultFloat = 18)
public void setTextSize(TextView view, float fontSize) {
log("setTextSize ->" + view.toString() + " " + fontSize);
view.setTextSize(fontSize);
}
@ReactProp(name = ViewProps.COLOR, defaultInt = Color.BLACK)
public void setTextColor(TextView view, int textColor) {
log("setTextColor ->" + view.toString() + " " + textColor);
view.setTextColor(textColor);
}
@ReactProp(name = "isAlpha", defaultBoolean = false)
public void setTextAlpha(TextView view, boolean isAlpha) {
log("setTextAlpha ->" + view.toString() + " " + isAlpha);
if (isAlpha) {
view.setAlpha(0.5f);
} else {
}
}
}
2、ViewManager 添加到ReactPackage
package react.view;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
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;
/**
* Created by Administrator on 2016/12/7.
*/
public class MyViewReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
List<ViewManager> list = new ArrayList<>();
list.add(new MyViewManager());
return list;
}
}
3、ReactPackage 添加到Application
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new VectorIconsPackage(),
new PickerPackage(),
new MyModuleReactPackage(),
new MyViewReactPackage()
);
}
};
4、js 定义组件
myTextView .js
/**
* Created by Administrator on 2016/12/7.
*/
import { PropTypes } from 'react';
import { requireNativeComponent } from 'react-native';
var myTextView = {
name: 'MyTextView',
propTypes: {
text: PropTypes.string,
fontSize: PropTypes.number,
color: PropTypes.number,
isAlpha: PropTypes.bool,
backgroundColor:PropTypes.number,
testID:PropTypes.string,
accessibilityComponentType:PropTypes.string,
accessibilityLabel:PropTypes.string,
accessibilityLiveRegion:PropTypes.string,
renderToHardwareTextureAndroid:PropTypes.bool,
importantForAccessibility:PropTypes.string,
onLayout:PropTypes.bool,
}
}
module.exports = requireNativeComponent('MyTextView', myTextView);
其中的propTypes text 为java中MyViewManager定义的@ReactProp注解 name值
5、使用 就可以和正常的组件一样使用
/**
* Created by Administrator on 2016/12/7.
*/
import React, { Component } from 'react';
import {
StyleSheet,
requireNativeComponent,
PropTypes,
Dimensions,
Alert,
Text,
View
} from 'react-native'
import MyTextView from './componet/MyTextView.js'
const dimensions = Dimensions.get('window');
class NativeViewDemo extends Component {
// 构造
constructor(props) {
super(props);
// 初始状态
this.state = {};
}
_onPress = ()=> {
Alert.alert("onPress")
}
// 渲染
render() {
/*
在styles中使用与在属性中使用效果是一样的,属性中使用会覆盖样式中的使用
*/
return (
<View style={{flex:1}}>
<MyTextView
onPress={this._onPress}
style={styles.textDefault}
isAlpha={false}
fontSize={50}
backgroundColor={0x4eff0000}
text="你好"
/>
</View>
);
}
}
const styles = StyleSheet.create({
textDefault: {
width: dimensions.width,
paddingLeft: 20,
fontSize: 10,
height: 100,
},
});
export default NativeViewDemo;
6、事件处理 相互绑定
java 发送事件
public class MyViewManager extends SimpleViewManager<TextView> {
@Override
public String getName() {
return "MyTextView";
}
@Override
protected TextView createViewInstance(final ThemedReactContext reactContext) {
final TextView textView = new TextView(reactContext.getBaseContext());
textView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
log("onTouch() called with: " + "v = [" + v + "], event = [" + event + "]");
if (event.getAction() == MotionEvent.ACTION_DOWN) {
WritableMap nativeEvent = Arguments.createMap();
nativeEvent.putString("message", "ACTION_DOWN");
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
textView.getId(), "topChange", nativeEvent
);
}
return true;
}
});
return textView;
}
```
关键代码
```
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
textView.getId(), "topChange", nativeEvent
);```
和自定义module第三种发送事件类似,
**eventName topChange随便写的话,在js中是收不到**
查看UIManagerModuleConstants.java 映射关系 *不明白*
js中接收
```
/**
* Created by Administrator on 2016/12/7.
*/
import React,{
Component,PropTypes }
from 'react';
import {
requireNativeComponent
,Alert
} from 'react-native';
var myTextView = {
name: 'MyTextView', //MyViewManager getName的返回值
propTypes: {
text: PropTypes.string,
fontSize: PropTypes.number,
color: PropTypes.number,
isAlpha: PropTypes.bool,
backgroundColor: PropTypes.number,
testID: PropTypes.string,
accessibilityComponentType: PropTypes.string,
accessibilityLabel: PropTypes.string,
accessibilityLiveRegion: PropTypes.string,
renderToHardwareTextureAndroid: PropTypes.bool,
importantForAccessibility: PropTypes.string,
onLayout: PropTypes.bool,
}
}
//module.exports = requireNativeComponent('MyTextView', myTextView);
var RCTMyView = requireNativeComponent('MyTextView', myTextView, {
/*能不希望原生专用的属性出现在API之中,也就不希望把它放到propTypes里。
可是如果你不放的话,又会出现一个报错。解决方案就是带上nativeOnly选项*/
nativeOnly: {
onChange: true,
}
});
class MyView extends Component {
constructor() {
super();
}
_onChange = (event:Event)=> {
console.log("_onChange", event);
if (!this.props.onMyPress) {
return;
}
if (event.nativeEvent.message === 'ACTION_DOWN') {
this.props.onMyPress();
return;
}
}
render() {
/*java发送的是topChange在此接收的是onChange因为在UIManagerModuleConstants.java中定义了映射关系*/
return <RCTMyView
{...this.props}
onChange={this._onChange}/>
}
}
MyView.propTypes = {
/*propTypes和上面的意思应该差不多*/
onMyPress: React.PropTypes.func,
}
module.exports = MyView;
```
### 事件 发送自定义事件