是否可以将使用本机反应制作的GUI与本机代码(kotlin)中的实用程序方法相结合?



我有一个完全使用 react native 制作的应用程序。这几乎是一个待办事项列表,这是结构:

<SafeAreaView style={styles.container}>
<Text style={styles.title} >Registro de pacientes</Text>
{loading && (
<ActivityIndicator
style={styles.loading}
size="large"
color="#0066ff"
/>
)}
{!loading && (
<ListaPacientes  
pacientes={pacientes} 
onUpdate={this.handleUpdate}
/>
)}
</SafeAreaView>

这是列表:

<SectionList
sections={
pacientes && pacientes.length ? 
[
{title: "Pacientes sin registrar", data: pacientes.filter(paciente => !paciente.done)},
{title: "Pacientes registrados", data: pacientes.filter(paciente => paciente.done)}
] : []
}
keyExtractor={paciente => paciente.id}
renderItem={({item}) => renderItem(item)}
renderSectionHeader={renderSectionHeader}
style={styles.container}
ItemSeparatorComponent={renderSeparator}
ListEmptyComponent={renderEmptyComponent}
stickySectionHeadersEnabled={true}
/>

这将获取客户端列表并显示其名称。单击后,它们将从列表中删除。很简单。

问题是,必须从 csv 文件中读取客户端列表,然后单击后更新 csv。我已经有一段代码可以做到这一点。但是,它是用 kotlin 编写的(它是为另一个项目编码的(。

我不必在 react native 中再次对数据进行整个获取/读取/处理/更新,我可以以某种方式使用我已经拥有的 kotlin 代码吗?如果是这样,请提供一个例子来说明如何做到这一点?

编辑:为了澄清,我有一个 kotlin 方法,该方法返回一个字符串的 ArrayList,其中包含我要存储在列表中的名称。我怎样才能从javascript调用该方法,获取arraylist,并将其用作我的SectionList的数据源?

lateinit var pacientes: Array<String>
@ReactMethod
fun getListaPacientes() : Array<String> {
return pacientes
}

像这样的东西?


var res = []
res = ListaPacientesModulo.getListaPacientes()

谢谢。

我已经通过以下操作解决了问题:

首先,事实证明,如果您使用的是expo,则无法使用本机模块,因此我不得不将其弹出。

其次,为了使用 kotlin,您必须手动安装插件(您可以这样做,但我认为不值得麻烦,所以我使用 java 代替(

当涉及到代码时,你需要使用"WritableArray"和"WritableMap"。

private static WritableMap convertJsonToMap(JSONObject jsonObject) throws JSONException {
WritableMap map = new WritableNativeMap();
Iterator<String> iterator = jsonObject.keys();
while (iterator.hasNext()) {
String key = iterator.next();
Object value = jsonObject.get(key);
if (value instanceof JSONObject) {
map.putMap(key, convertJsonToMap((JSONObject) value));
} else if (value instanceof Boolean) {
map.putBoolean(key, (Boolean) value);
} else if (value instanceof Integer) {
map.putInt(key, (Integer) value);
} else if (value instanceof Double) {
map.putDouble(key, (Double) value);
} else if (value instanceof String) {
map.putString(key, (String) value);
} else {
map.putString(key, value.toString());
}
}
return map;
}

所有 react 方法都必须返回 void,使用 promise 或回调与 react 通信

@ReactMethod
public void readCSV(Promise promise) {
//Load the list
for(int i = 0; i < source.size(); i++) {
this.listWithPeople.add(new Person(source.get(i), startTimes.get(i)));
}
//Pepare the map
WritableArray defList = new WritableNativeArray();
Gson g = new Gson();
for(Person p : this.listWithPeople) {
JSONObject jo = new JSONObject(g.toJson(p));
WritableMap wm = convertJsonToMap(jo);
defList.pushMap(wm);
}

promise.resolve(defList);
}

最后,在您的.js文件上:

import { NativeModules } from 'react-native';
const { NativeModuleName } = NativeModules;
const getPacientes = async () => {
var peopleList = []
var res = await NativeModuleName.readCSV()
for(var i = 0; i < res.length; i++) {
peopleList.push(newPerson({ name: res[i].name, star: res[i].date, done: false }))
}
return peopleList
}

在安卓部分,你还需要这个类:

模块名称包.java

public class ModuleNamePackage implements ReactPackage {
@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
List<NativeModule> nativeModules = new ArrayList<>();
nativeModules.add(new NativeModuleName(reactContext));
return nativeModules;
}
@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}

在 MainApplication.java 中,您需要将软件包添加到软件包列表中:

private final ReactNativeHost mReactNativeHost =
new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
packages.add(new ModuleNamePackage());
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};

假设你的 Kotlin 代码构建得很好,即每个方法都与 UI 分离,你可以创建一个从react-nativeKotlin的桥梁。

您需要创建一个包、一个模块和你的 Bridge 类。

import com.facebook.react.bridge.ReactMethod
class CsvManager(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
// the bridge 
@ReactMethod
fun update(csvUrl: String, data: List<String>) {
// your code to load or update the CSV
}
}

在你的顶级项目中,创建一个新的 JS,如kotlinCsv.js

import { NativeModules } from 'react-native'
module.exports = NativeModules.CsvModule

应用中的任何位置:

import KotlinCsvUpdater from './kotlinCsv'
let myArray = []
KotlinCsvUpdater.update('pathToMyFile', myArray)

最新更新