我有一个完全使用 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-native
到Kotlin
的桥梁。
您需要创建一个包、一个模块和你的 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)