简体   繁体   中英

How to select multiple items in FlatList, highlight them and keep them saved in React Native

I want to select multiple items from the FlatList. Whenever, I click them, they should be highlighted and they should be saved in some state variable

I am using 'react-native-android-installed-apps' to get a list of all the installed apps in a FLatList

This is what I have done up till now:

import React, {Component} from 'react';
import {View, Text, Image, FlatList, Dimensions, TouchableOpacity} from 'react-native';
import RNAndroidInstalledApps from 'react-native-android-installed-apps';

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            data: []
        };
    }

    componentDidMount() {
        this.check();
    }

    check = () => {
        let combine = [];
        RNAndroidInstalledApps.getApps()
            .then(apps => {
                if(apps.length > 0) {
                    for(let i = 0; i< apps.length ; i++) {
                        thisApp = apps[i];
                        const obj = {'appName': thisApp.appName, 'icon': thisApp.icon};
                        combine.push(obj);
                    }
                }
                this.setState({
                    data: combine
                });
                // console.log(this.state.data);
            });
    };

    renderSeperator = () => {
        return(
            <View
                style={{
                    height: 1,
                    backgroundColor: '#CED0CE',
                }}
            />
        );
    };

    render() {
        return(
        <FlatList
                data={this.state.data}
                renderItem={({ item }) =>(
                    <TouchableOpacity
                        style={{flexDirection:'row', padding: 5 }}
                    >
                        <Image
                            style={{width: 51, height: 51, resizeMode: 'contain', flex: 1 }}
                            source={{ uri: `data:image;base64,${item.icon}` }}
                        />
                        <Text style={{alignSelf: 'center', marginStart: 10, flex: 5 }}>{item.appName}</Text>
                    </TouchableOpacity>
                )}
                keyExtractor={(item) => item.appName}
                ItemSeparatorComponent={this.renderSeperator}
        />
        );
    }
}

export default App;

I expect to highlight each item when it is selected, and save it's data in some state variable

Let's do this with some array checkList and we put it inside state, the FlatList look like this:

<FlatList
     data={this.state.data}
     renderItem={({ item }) =>(
    <TouchableOpacity
    onPress={()=>{
      const list = this.state.checkList; 
      list.push(item)
      this.setState({checkList: list})
    }}
    style={{flexDirection:'row', padding: 5 }} >
  <Image
       style={{width: 51, height: 51, resizeMode: 'contain', flex: 1 }}
       source={{ uri: `data:image;base64,${item.icon}` }}
      />
  <Text style={{alignSelf: 'center', marginStart: 10, flex: 5 }}>{item.appName}</Text>
       </TouchableOpacity>
           )}
           keyExtractor={(item) => item.appName}
           ItemSeparatorComponent={this.renderSeperator}
        />

this way you save all item that clicked, you can develop it more and drop from the list when it clicked again or change color for the check list

Figured it out:

import React, {Component} from 'react';
import {View, Text, Image, FlatList, TouchableOpacity} from 'react-native';
import RNAndroidInstalledApps from 'react-native-android-installed-apps';

var selected = [];
class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            data: [],
            itemChecked: []
        };
    }

    componentDidMount() {
        this.check();
    }

    check = () => {
        let combine = [];
        RNAndroidInstalledApps.getApps()
            .then(apps => {
                if(apps.length > 0) {
                    for(let i = 0; i< apps.length ; i++) {
                        thisApp = apps[i];
                        const obj = {'appName': thisApp.appName, 'icon': thisApp.icon, 'isSelect': false};
                        combine.push(obj);
                    }
                }
                this.setState({
                    data: combine
                });
                // console.log(this.state.data);
            });
    };

    renderSeperator = () => {
        return(
            <View
                style={{
                    height: 1,
                    backgroundColor: '#CED0CE',
                }}
            />
        );
    };

    selectItem = (item) => {
        item.isSelect = !item.isSelect;
        if(item.isSelect){
            selected.push(item.appName);
        } else {
            for(let i = 0; i < selected.length; i++) {
                if(selected[i] === item.appName) {
                    selected.splice(i, 1)
                }
            }
        }
        this.setState({itemChecked: selected});
    };

    renderRow = (item) => {
        const isSelected = item.isSelect;
        const viewStyle = isSelected ? styles.selected : styles.normal;
        return(
            <TouchableOpacity
                style={viewStyle}
                onPress={() => this.selectItem(item)}
            >
                <Image
                    style={{width: 51, height: 51, resizeMode: 'contain', flex: 1 }}
                    source={{ uri: `data:image;base64,${item.icon}` }}
                />
                <Text style={{alignSelf: 'center', marginStart: 10, flex: 5 }}>{item.appName}</Text>
            </TouchableOpacity>
        );
    };

    render() {
        return(
        <FlatList
                data={this.state.data}
                renderItem={({item}) => this.renderRow(item)}
                keyExtractor={(item) => item.appName}
                ItemSeparatorComponent={this.renderSeperator}
                extraData={this.state}
        />
        );
    }
}

const styles = {
    selected: {
        flexDirection: 'row',
        padding: 5,
        backgroundColor: 'blue'
    },
    normal: {
        flexDirection: 'row',
        padding: 5
    }    
}

export default App;

For that, you can use the library react-native-sectioned-multi-select

Documentation in https://github.com/renrizzolo/react-native-sectioned-multi-select

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM