【React Native】文件翻譯閱讀紀錄 - 指南(Android) - 原生 UI 組件
Facebook Open Source React Native
與本機模塊指南一樣,這也是一個更高級的指南,假設您對Android SDK編程有些熟悉。本指南將向您展示如何構建本機UI組件,引導您完成核心React Native庫中可用的現有ImageView組件的子集的實現。
ImageView 示例
通過擴展ViewManager或更常見的SimpleViewManager來創建和操作本機視圖。在這種情況下,SimpleViewManager很方便,因為它應用了常見屬性,例如背景顏色,不透明度和Flexbox佈局。
這些子類本質上是單例 - 每個只有一個實例由橋創建。它們向NativeViewHierarchyManager提供本機視圖,該視圖委託給它們以根據需要設置和更新視圖的屬性。 ViewManagers通常也是視圖的代理,通過網橋將事件發送回JavaScript。
1. 創建 ViewManager 子類
...
public class ReactImageManager extends SimpleViewManager<ReactImageView> {
public static final String REACT_CLASS = "RCTImageView";
@Override
public String getName() {
return REACT_CLASS;
}
2. 實現方法 createViewInstance
@Override
public ReactImageView createViewInstance(ThemedReactContext context) {
return new ReactImageView(context, Fresco.newDraweeControllerBuilder(), mCallerContext);
}
3. 使用@ReactProp(或@ReactPropGroup)註釋公開視圖屬性設置器
註釋@ReactProp有一個String類型的強制參數名稱。分配給鏈接到setter方法的@ReactProp註釋的名稱用於引用JS端的屬性。
除了名稱,@ ReactProp註釋可能採用以下可選參數:defaultBoolean,defaultInt,defaultFloat。這些參數應該是相應的基本類型(相應的是boolean,int,float),並且如果setter引用的屬性已從組件中刪除,則提供的值將傳遞給setter方法。請注意,“默認”值僅為基本類型提供,如果setter是某種複雜類型,則在相應屬性被刪除時,null將作為默認值提供。
使用@ReactPropGroup註釋的方法的setter聲明要求與@ReactProp不同,請參閱@ReactPropGroup註釋類docs以獲取有關它的更多信息。 @ReactProp(name = "src")
public void setSrc(ReactImageView view, @Nullable ReadableArray sources) {
view.setSource(sources);
}
@ReactProp(name = "borderRadius", defaultFloat = 0f)
public void setBorderRadius(ReactImageView view, float borderRadius) {
view.setBorderRadius(borderRadius);
}
@ReactProp(name = ViewProps.RESIZE_MODE)
public void setResizeMode(ReactImageView view, @Nullable String resizeMode) {
view.setScaleType(ImageResizeMode.toScaleType(resizeMode));
}
4. 註冊 ViewManager
@Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(
new ReactImageManager()
);
}
5. 實現 JavaScript 模塊// ImageView.js
import PropTypes from 'prop-types';
import {requireNativeComponent, ViewPropTypes} from 'react-native';
var iface = {
name: 'ImageView',
propTypes: {
src: PropTypes.string,
borderRadius: PropTypes.number,
resizeMode: PropTypes.oneOf(['cover', 'contain', 'stretch']),
...ViewPropTypes, // include the default view properties
},
};
module.exports = requireNativeComponent('RCTImageView', iface);
requireNativeComponent
通常有兩個參數,第一個是本機視圖的名稱,第二個是描述組件接口的對象。組件接口應聲明用於調試消息的友好名稱,並且必須聲明由Native View反映的propTypes。 propTypes用於檢查用戶使用本機視圖的有效性。請注意,如果您需要JavaScript組件執行的不僅僅是指定名稱和propTypes,比如執行自定義事件處理,則可以將本機組件包裝在普通的反應組件中。在這種情況下,您希望將包裝器組件而不是iface傳遞給requireNativeComponent。這在下面的MyCustomView示例中說明。
活動class MyCustomView extends View {
...
public void onReceiveNativeEvent() {
WritableMap event = Arguments.createMap();
event.putString("message", "MyMessage");
ReactContext reactContext = (ReactContext)getContext();
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
getId(),
"topChange",
event);
}
}
public class ReactImageManager extends SimpleViewManager<MyCustomView> {
...
public Map getExportedCustomBubblingEventTypeConstants() {
return MapBuilder.builder()
.put(
"topChange",
MapBuilder.of(
"phasedRegistrationNames",
MapBuilder.of("bubbled", "onChange")))
.build();
}
}
// MyCustomView.js
class MyCustomView extends React.Component {
constructor(props) {
super(props);
this._onChange = this._onChange.bind(this);
}
_onChange(event: Event) {
if (!this.props.onChangeMessage) {
return;
}
this.props.onChangeMessage(event.nativeEvent.message);
}
render() {
return <RCTMyCustomView {...this.props} onChange={this._onChange} />;
}
}
MyCustomView.propTypes = {
/**
* Callback that is called continuously when the user is dragging the map.
*/
onChangeMessage: PropTypes.func,
...
};
var RCTMyCustomView = requireNativeComponent(`RCTMyCustomView`, MyCustomView, {
nativeOnly: {onChange: true}
});
0 意見