突出显示从 SearchBar 生成的 React Native FlatList 的最佳实践

问题描述 投票:0回答:1

我有一个可用的 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 };```
react-native expo stylesheet
1个回答
0
投票

我能够通过使用标志 -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 };
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.