Commit 774edc0c by leiyongsheng

添加native模块

parent 142f06bb
......@@ -6,7 +6,7 @@
* @flow strict-local
*/
import React from 'react';
import React, { useState } from 'react';
import {
NativeModules,
SafeAreaView,
......@@ -17,8 +17,13 @@ import {
Button,
StatusBar,
Alert,
Image,
TextInput,
DeviceEventEmitter,
} from 'react-native';
import BMCUI from './ui.js'
import { BMCUI } from './ui.js'
import CustomerView from './CustomerView.js'
import CustomRoundImageView from './RoundedImage.js'
import {
Header,
......@@ -28,7 +33,23 @@ import {
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
const App: () => React$Node = () => {
async function showConfirmVsCancelPromiseDialog(msg, leftTip, rightTip) {
try {
const {
right,
left
} = await BMCUI.showConfirmVsCancelPromiseDialog(msg, leftTip, rightTip);
console.log(
"你点击了按钮,结果为:" + left + " / " + right
);
} catch (e) {
console.error(e);
}
}
const App = () => {
var index = 0;
return (
<>
<StatusBar barStyle="dark-content" />
......@@ -36,22 +57,44 @@ const App: () => React$Node = () => {
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={styles.scrollView}>
<Header />
{global.HermesInternal == null ? null : (
<View style={styles.engine}>
<Text style={styles.footer}>Engine: Hermes(need config!!!!)</Text>
</View>
)}
<View style={styles.buttonContainer}>
<CustomerView />
</View>
<View style={styles.body}>
<View style={styles.buttonContainer}>
{Platform.OS == 'android' ? (
<CustomRoundImageView src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1598436038838&di=d725130cf6ca00e920ad68b21ba72f5c&imgtype=0&src=http%3A%2F%2Ft9.baidu.com%2Fit%2Fu%3D1307125826%2C3433407105%26fm%3D79%26app%3D86%26f%3DJPEG%3Fw%3D5760%26h%3D3240"
cornerRadius={30} borderWidth={2} style={{ width: 200, height: 160 }} />
) : null
}
<Button
style={styles.buttonStyle}
onPress={() => {
index++;
DeviceEventEmitter.emit('msg', '发送了个通知:' + index);
}}
title="发送消息"
/>
</View>
<View style={styles.buttonContainer}>
<Button
style={styles.buttonStyle}
onPress={() => {
if (Platform.OS == 'android') {
// BMCUI.show('"你点击了按钮!");\
console.log(NativeModules);
NativeModules.BMCUI.show("你点击了按钮111!");
// NativeModules.BMCUI.showWithDuration("你点击了按钮!", NativeModules.BMCUI.SHORT);
// Alert.alert("你点击了按钮");
} else {
Alert.alert("ios undefine");
}
}}
title="吐司"
/>
......@@ -60,6 +103,7 @@ const App: () => React$Node = () => {
<Button
style={styles.buttonStyle}
onPress={() => {
if (Platform.OS == 'android') {
BMCUI.showConfirmDialogWithCancelable(false, "你点击了按钮222!", "确定", (result) => {
console.log("你点击了取确定按钮,结果为:" + result);
});
......@@ -69,6 +113,9 @@ const App: () => React$Node = () => {
// BMCUI.showConfirmDialogWithCancelableError((result) => {
// console.log("你点击了确定,结果为:" + result);
// }, true, "你点击了按钮222!", "确定");
} else {
Alert.alert("ios undefine");
}
}}
title="单按钮提示框"
/>
......@@ -77,11 +124,16 @@ const App: () => React$Node = () => {
<Button
style={styles.buttonStyle}
onPress={() => {
BMCUI.showConfirmVsCancelDialog("你点击了按钮333!", "取消", "确定", (result) => {
console.log("你点击了取消单按钮,结果为:" + result);
}, (result) => {
console.log("你点击了取确定按钮,结果为:" + result);
});
if (Platform.OS == 'android') {
// BMCUI.showConfirmVsCancelDialog("你点击了按钮333!", "取消", "确定", (result) => {
// console.log("你点击了取消单按钮,结果为:" + result);
// }, (result) => {
// console.log("你点击了取确定按钮,结果为:" + result);
// });
showConfirmVsCancelPromiseDialog("你点击了按钮333!", "取消", "确定");
} else {
Alert.alert("ios undefine");
}
}}
title="双按钮提示框"
/>
......
import React, { useState } from 'react';
import {
View,
Text,
Image,
TextInput,
DeviceEventEmitter,
TouchableHighlight,
TouchableNativeFeedback,
Platform,
Alert
} from 'react-native';
import { BMCUI, ImagePicker } from './ui.js'
async function choosePic(openCamera, selectPic) {
try {
const {
path,
paths
} = await ImagePicker.choosePic(openCamera, selectPic);
console.log("path:" + path + " / paths:" + paths);
BMCUI.show("path:" + path + " / paths:" + paths);
} catch (e) {
console.error(e);
}
}
function imageClick() {
if (Platform.OS == 'android') {
choosePic(ImagePicker.OPEN_CAMERA, ImagePicker.SELECTED_IMAGES);
} else {
Alert.alert("ios undefine");
}
}
function Cat(props) {
return (
<View style={{ flexDirection: "row" }}>
<TouchableNativeFeedback onPress={imageClick}>
<Image
source={{
uri: 'https://reactnative.dev/docs/assets/p_cat2.png',
}}
style={{ width: 120, height: 120 }}
/>
</TouchableNativeFeedback>
<Text style={{ padding: 10, fontSize: 42, flexWrap: "wrap" }}>
{props.textTrans.split(' ').map((word) => word && '🍕').join(' ')}
</Text>
</View>
);
}
export default class CustomerView extends React.Component {
constructor(props) {
super(props);
console.log("CustomerView constructor");
/**
* useState does two things:
* 1:it creates a “state variable” with an initial value—in this case the state variable is textTrans and its initial value is ''
* 2:it creates a function to set that state variable’s value—setInputText
* It doesn’t matter what names you use. But it can be handy to think of the pattern as [<getter>, <setter>] = useState(<initialValue>).
*
* 虽然textTrans使用了常量关键字const,但它看起来还是可以修改!
* What is happening is when a state-setting function like setInputText is called, its component will re-render.
* In this case the Cat function will run again—and this time, useState will give us the next value of textTrans.
*/
//const [textTrans, setInputText] = useState('');
this.state = {
textTrans: ''
};
}
componentDidMount() {
console.log("CustomerView componentDidMount");
this.eventListener = DeviceEventEmitter.addListener('msg', (a) => {
// alert('收到通知:' + a);
console.log("收到通知:" + a);
if (a && a.test) {
tip = a.test
} else {
tip = a
}
BMCUI.showConfirmDialogWithCancelable(false, "收到新消息:" + tip, "确定", (result) => {
console.log("你点击了取确定按钮,结果为:" + result);
});
});
}
shouldComponentUpdate(nextProps, nextState, nextContext) {
console.log("CustomerView shouldComponentUpdate nextProps:" + nextProps);
console.log("CustomerView shouldComponentUpdate nextState.textTrans:" + nextState.textTrans + " / currState.textTrans:" + this.state.textTrans);
return (nextState.textTrans || this.state.textTrans)
&& (nextState.textTrans.split(' ').length != this.state.textTrans.split(' ').length
|| (nextState.textTrans.length == 1 && this.state.textTrans.length == 0))
}
componentWillUnmount() {
console.log("CustomerView componentWillUnmount");
this.eventListener.remove(); // Removes the listener
}
componentDidCatch(error, errorInfo) {
console.log("CustomerView componentDidCatch");
}
render() {
return (
<>
<Cat textTrans={this.state.textTrans} />
<TextInput
style={{
height: 40,
margin: 10,
borderColor: 'gray',
borderWidth: 1
}}
placeholder="Type here to translate!"
onChangeText={text => this.setState({ textTrans: text })}
defaultValue={this.state.textTrans}
/>
</>
);
}
}
\ No newline at end of file
import React from 'react';
import PropTypes from "prop-types";
import { requireNativeComponent, View } from 'react-native';
import { BMCUI, ImagePicker } from './ui.js'
/**
* Composes `View`.
*
* - src: string
* - borderWidth: number
* - cornerRadius: number
* - resizeMode: 'contain' | 'cover' | 'stretch' | 'center'
*/
// const RoundImage = requireNativeComponent('RoundImage', {
// propTypes: {
// src: PropTypes.string,//定义传输属性类型
// cornerRadius: PropTypes.number,
// borderWidth: PropTypes.number,
// ...View.propTypes // 包含默认的View的属性
// }
// });
const RoundImage = requireNativeComponent('RoundImage');
async function choosePic(openCamera, selectPic, callback) {
try {
const {
path,
paths
} = await ImagePicker.choosePic(openCamera, selectPic);
console.log("path:" + path + " / paths:" + paths);
BMCUI.show("path:" + path + " / paths:" + paths);
if (path) {
callback(path)
} else if (paths && paths.length > 0) {
callback(paths[0])
}
} catch (e) {
console.error(e);
}
}
function imageClick(callback) {
if (Platform.OS == 'android') {
choosePic(ImagePicker.OPEN_CAMERA, ImagePicker.SELECTED_IMAGES, callback);
} else {
Alert.alert("ios undefine");
}
}
export default class CustomRoundImageView extends React.Component {
constructor(props) {
super(props);
this._onChange = this._onChange.bind(this);
this.state = {
imgUrl: this.props.src
};
}
componentDidMount() {
console.log("CustomRoundImageView componentDidMount : " + RoundImage + " / default img:" + this.state.imgUrl);
}
_onChange(event) {
console.log("onChange props:" + this.props + " / event:" + event);
if (event.nativeEvent.message) {
BMCUI.show("get event:" + event.nativeEvent.message);
}
imageClick((path) => {
this.setState({
// imgUrl: "https://reactnative.dev/docs/assets/p_cat2.png"
imgUrl: path
});
})
if (!this.props.onChangeMessage) {
return;
}
this.props.onChangeMessage(event.nativeEvent.message);
}
render() {
return <RoundImage {...this.props} src={this.state.imgUrl} style={this.props.style} onChange={this._onChange} />;
}
}
CustomRoundImageView.propTypes = {
/**
* Callback that is called continuously when the user is dragging the map.
*/
onChangeMessage: PropTypes.func,
src: PropTypes.string,//定义传输属性类型
cornerRadius: PropTypes.number,
borderWidth: PropTypes.number,
};
\ No newline at end of file
android @ 480f15c7
Subproject commit 5308f0b69d84c40a54636b3c97b4fc6c95840eea
Subproject commit 480f15c72f5fa19e9214f06f42dd09953a092d58
......@@ -4,7 +4,11 @@
*
* 1. String message: A string with the text to toast
*/
import { NativeModules } from 'react-native';
import { NativeModules, requireNativeComponent } from 'react-native';
// 下一句中的BMCUI即对应上文
// public String getName()中返回的字符串
export default NativeModules.BMCUI;
\ No newline at end of file
//使用export default时,对应的import语句不需要使用大括号
//export default NativeModules.BMCUI;
//不使用export default时,对应的import语句需要使用大括号
export var BMCUI = NativeModules.BMCUI;
export var ImagePicker = NativeModules.ImagePicker;
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment