我有一个可用的 React Native 搜索栏,按键时会填充 FlatList 视图。当按下 Flatlist 元素时,我想仅突出显示所选元素。关于如何在 React Native 中完成此操作有什么想法吗?
import React, { useState, Component, useEffect } from "react";
import { SearchBar } from 'react-native-elements';
import {
StyleSheet,
Text,
View,
ScrollView,
Image,
TextInput,
Button,
Alert,
TouchableOpacity,
Modal,
Pressable,
ActivityIndicator,
FlatList
} from "react-native";
import { useIsFocused } from "@react-navigation/native";
import { registerRootComponent } from 'expo';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import { useNavigation } from '@react-navigation/native';
import constants from './Constants.js';
import { styles } from './CommonStylesWeb.js';
import RNPickerSelect from 'react-native-picker-select';
import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context';
const CancerHomepageWeb = ({navigation}) => {
const [cancerWiki, setCancerWiki] = useState("");
const [cancerType, setCancerType] = useState("");
const [selectedValue, setSelectedValue] = useState(null);
const [selectedLabel, setSelectedLabel] = useState(null);
const [options, setOptions] = useState([]);
const [cancerWikiContent, setCancerWikiContent] = useState("");
const [loadingWiki, setLoadingWiki] = useState(null);
const [loadingCancers, setLoadingCancers] = useState(null);
console.log("navigation ", navigation);
useEffect(() => {
const getData = async () => {
// show loading icon
setLoadingWiki(true);
var urlCancerWiki = await constants.getServerURL() + 'cancers_wiki';
console.warn("NEW COMMENT")
console.warn(urlCancerWiki);
let resultCancerWiki = await fetch(urlCancerWiki, {
method: "GET", mode: 'cors'
}).then(response => response.json())
.then(response => {
if (response.status == 200) {
setLoadingWiki(false)
console.warn(response.content)
setCancerWiki(response.content)
} else {
setLoadingWiki(false)
console.warn(response.message)
setGeneWiki(response.message)
}
});
};
getData();
}, []);
async function handleChangeCancer(value, label) {
console.warn("CANCER HAS CHANGED");
setSelectedValue(value);
console.warn(value)
if(label) {
setCancerWiki("");
setCancerWikiContent("");
setLoadingWiki(true);
const url = await constants.getServerURL() + 'cancer_wiki';
console.warn(url);
let result = fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: value}),
mode: 'cors'
}).then(response => response.json())
.then(response => {
if (response.status == 200) {
setLoadingWiki(false);
setCancerWikiContent(response.content)
setCancerWiki("")
} else {
setLoadingWiki(false)
console.warn(response.message)
setGeneWiki(response.message)
}
});
}
};
const searchCancers = async() => {
const url = await constants.getServerURL() + 'cancer_name';
console.warn(url);
console.warn(cancerType);
if (cancerType.length >= 3) {
setLoadingCancers(true);
let result = fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ cancer_type: cancerType}),
mode: 'cors'
}).then(response => response.json())
.then(response => {
setOptions([]);
optionsTemp = [];
console.warn("GETTING CANCER RESPONSE")
console.warn(response)
if (response.status == 200) {
setLoadingCancers(false);
//setCancer = response.cancers
console.warn("VALID CANCER RESPONSE")
response.content.map( (cancer) => {
optionsTemp.push(new Object({label:cancer.name , value: cancer.id}));
});
console.warn(optionsTemp)
setOptions(optionsTemp);
} else {
setLoadingCancers(false);
console.warn("Error retrieving Cancer");
//setErrorMessage("Error Getting Cancers!");
//setErrorVisible(true);
}
});
}
}
const renderItem = ({ item }) => (
<TouchableOpacity onPress={() => handleChangeCancer(item.value,item.label)}>
<Text style={styles.item}>{item.label}</Text>
</TouchableOpacity>
);
return (
<View style={styles.container}>
<StatusBar style="auto" />
<View>
<SearchBar
style={styles.searchBar}
placeholder="Search by Cancer Type"
onChangeText={(cancerType) => setCancerType(cancerType)}
value={cancerType}
onKeyPress={searchCancers}
/>
{loadingCancers &&
<ActivityIndicator size="large" />
}
<FlatList
data={options}
renderItem={renderItem}
keyExtractor={item => item.value}
style={styles.dropdown}
/>
</View>
<View>
<Text style={{ fontSize: 20 }}>Cancers</Text>
</View>
<ScrollView>
<View style={styles.wikiView}>
<Text>{cancerWikiContent}</Text>
<Text>{cancerWiki}</Text>
{loadingWiki &&
<SafeAreaProvider>
<SafeAreaView style={[styles.loadingContainer, styles.loadingHorizontal]}>
<ActivityIndicator size="large" />
</SafeAreaView>
</SafeAreaProvider>
}
</View>
</ScrollView>
</View>
);
}
export { CancerHomepageWeb };
我正在考虑为选定的 flatList 元素添加不同的样式。 (即itemSelected)因此添加一个条件来更改所选项目的样式。但我必须首先将默认样式(即项目)应用于所有 FlatList 元素,这样我一次只能突出显示一个元素。
import {
StyleSheet,
Text,
View,
Image,
TextInput,
Button,
Alert,
TouchableOpacity,
} from "react-native";
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen';
const styles = StyleSheet.create({
searchBar: {
width: wp(60),
height: 10,
paddingLeft: 10,
flex: 1,
alignItems: "center",
justifyContent: "center",
}
dropdown: {
maxHeight: 150,
backgroundColor: 'white',
borderWidth: 1,
borderColor: 'gray',
borderRadius: 5,
marginTop: 5,
},
item: {
padding: 15,
fontSize: 16,
},
itemSelected: {
padding: 15,
fontSize: 16,
backgroundColor: '#2196F3',
color: "white"
}
});
export { styles };```
我能够通过使用标志 -highlightedIndex 来突出显示平面列表中的选定项目 - 然后应用突出显示的样式 - styles.itemSelected。这是对我有用的代码。
import { StatusBar } from "expo-status-bar";
import React, { useState, Component, useEffect } from "react";
import { SearchBar } from 'react-native-elements';
import {
StyleSheet,
Text,
View,
ScrollView,
Image,
TextInput,
Button,
Alert,
TouchableOpacity,
Modal,
Pressable,
ActivityIndicator,
FlatList
} from "react-native";
import { useIsFocused } from "@react-navigation/native";
import { registerRootComponent } from 'expo';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import { useNavigation } from '@react-navigation/native';
import constants from './Constants.js';
import { styles } from './CommonStylesWeb.js';
import RNPickerSelect from 'react-native-picker-select';
import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context';
const CancerHomepageWeb = ({navigation}) => {
const [cancerWiki, setCancerWiki] = useState("");
const [cancerType, setCancerType] = useState("");
const [selectedValue, setSelectedValue] = useState(null);
const [selectedLabel, setSelectedLabel] = useState(null);
const [options, setOptions] = useState([]);
const [cancerWikiContent, setCancerWikiContent] = useState("");
const [loadingWiki, setLoadingWiki] = useState(null);
const [loadingCancers, setLoadingCancers] = useState(null);
const [highlightedIndex, setHighlightedIndex] = useState(-1);
console.log("navigation ", navigation);
useEffect(() => {
const getData = async () => {
// show loading icon
setLoadingWiki(true);
var urlCancerWiki = await constants.getServerURL() + 'cancers_wiki';
console.warn("NEW COMMENT")
console.warn(urlCancerWiki);
let resultCancerWiki = await fetch(urlCancerWiki, {
method: "GET", mode: 'cors'
}).then(response => response.json())
.then(response => {
if (response.status == 200) {
setLoadingWiki(false)
console.warn(response.content)
setCancerWiki(response.content)
} else {
setLoadingWiki(false)
console.warn(response.message)
setGeneWiki(response.message)
}
});
};
getData();
}, []);
async function handleChangeCancer(value, label) {
// find index number for options
index = 0;
for (option of options) {
if (option.value == value) {
setHighlightedIndex(index);
}
index++;
}
console.warn("CANCER HAS CHANGED");
setSelectedValue(value);
console.warn(value)
if(label) {
setCancerWiki("");
setCancerWikiContent("");
setLoadingWiki(true);
const url = await constants.getServerURL() + 'cancer_wiki';
console.warn(url);
let result = fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: value}),
mode: 'cors'
}).then(response => response.json())
.then(response => {
if (response.status == 200) {
setLoadingWiki(false);
setCancerWikiContent(response.content)
setCancerWiki("")
} else {
setLoadingWiki(false)
console.warn(response.message)
setGeneWiki(response.message)
}
});
}
};
const searchCancers = async() => {
const url = await constants.getServerURL() + 'cancer_name';
console.warn(url);
console.warn(cancerType);
if (cancerType.length >= 3) {
setLoadingCancers(true);
let result = fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ cancer_type: cancerType}),
mode: 'cors'
}).then(response => response.json())
.then(response => {
setOptions([]);
optionsTemp = [];
console.warn("GETTING CANCER RESPONSE")
console.warn(response)
if (response.status == 200) {
setLoadingCancers(false);
//setCancer = response.cancers
console.warn("VALID CANCER RESPONSE")
response.content.map( (cancer) => {
optionsTemp.push(new Object({label:cancer.name , value: cancer.id}));
});
console.warn(optionsTemp)
setOptions(optionsTemp);
} else {
setLoadingCancers(false);
console.warn("Error retrieving Cancer");
//setErrorMessage("Error Getting Cancers!");
//setErrorVisible(true);
}
});
}
}
const renderItem = ({ item, index }) => (
<TouchableOpacity onPress={() => handleChangeCancer(item.value,item.label)}
style={[
styles.item,
highlightedIndex === index && styles.itemSelected,
]}
>
<Text>{item.label}</Text>
</TouchableOpacity>
);
return (
<View style={styles.container}>
<StatusBar style="auto" />
<View>
<SearchBar
style={styles.searchBar}
placeholder="Search by Cancer Type"
onChangeText={(cancerType) => setCancerType(cancerType)}
value={cancerType}
onKeyPress={searchCancers}
/>
{loadingCancers &&
<ActivityIndicator size="large" />
}
<FlatList
data={options}
renderItem={renderItem}
keyExtractor={item => item.value}
style={styles.dropdown}
/>
</View>
<View>
<Text style={{ fontSize: 20 }}>Cancers</Text>
</View>
<ScrollView>
<View style={styles.wikiView}>
<Text>{cancerWikiContent}</Text>
<Text>{cancerWiki}</Text>
{loadingWiki &&
<SafeAreaProvider>
<SafeAreaView style={[styles.loadingContainer, styles.loadingHorizontal]}>
<ActivityIndicator size="large" />
</SafeAreaView>
</SafeAreaProvider>
}
</View>
</ScrollView>
</View>
);
}
export { CancerHomepageWeb };