简体   繁体   中英

React-native FlatList rendering issue

THE PROBLEM

see the screenshot of probleme //below code is which loades the slider..you can also find the below snippet in ClassFlatListRender.js, when id of element passed through FlatList which equals to the selected Id then the audio slider should work, but if I trigger one audio file element all of the sliders are moving

   {id == this.state.selectedOptionId ?
    (<View style={[styles.viewBar, { flexDirection: 'row', }]}>
        <View style={[styles.viewBarPlay, { width: playWidthMessage }]} />
      </View)
      : 
  <View><Text>no slider<Text></View>}

THE CODE

The structure of my code is this: I have a container component with all the logic and state, which contains a FlatList component, which again contains a custom presentational List.

Container 
Custom list component that includes the FlatList component and the renderItem method
invokes classFlatList component (presentational, stateless)

The container includes this component

   <CustomList
      items={this.state.data} 
     />

CustomList:

export class CustomList extends Component {

    render() {

        const renderItem = ({ item }) => {
            return (
                <ClassFlatListRender
                    message={item.message}
                    id={item.id}
                    user={item.user}
                    timestamp={item.timestamp}
                    heights={item.heights}
                    url={item.url}
                    audioLength={item.audioLength}
                    type={item.type}
                />
            )
        }

        let { items } = this.props
        return (
            <View style={styles.container}>
                < FlatList
                    style={styles.container}
                    data={items.slice().sort((a, b) => b.timestamp - a.timestamp)}
                    // data={data}
                    renderItem={renderItem}
                    inverted={true}
                    extraData={items}
                    keyExtractor={(items) => `${items.timestamp}`}
                />
            </View>

        )
    }
} 

The ClassFlatListRender.js

export class ClassFlatListRender extends React.Component {
    constructor() {
        super();
        this.state = {

            update: false,
            currentPositionSec: 0,
            currentDurationSec: 0,
            playTime: '00:00:00',
            duration: '00:00:00',
            id: '',
            tempId: '',
            selectedOptionId: '',
            setId: '',
        };

        this.audioRecorderPlayer = new AudioRecorderPlayer();
        this.audioRecorderPlayer.setSubscriptionDuration(0.09); // optional. Default is 0.1
    }

   
    onStartPlay = async (id, url) => {
        console.log('onStartPlay');
        //? Custom path
        // const msg = await this.audioRecorderPlayer.startPlayer(this.path);

        //? Default path

        console.log("arvinf", url)

        const msg = await this.audioRecorderPlayer.startPlayer(url);
        console.log("msg", msg)
        const volume = await this.audioRecorderPlayer.setVolume(1.0);
        console.log(`file: ${msg}`, `volume: ${volume}`);

        this.audioRecorderPlayer.addPlayBackListener((e) => {


            this.setState({
                currentPositionSec: e.currentPosition,
                currentDurationSec: e.duration,
                // playWidth: (e.currentPosition / e.duration) * (screenWidth - 300)
                // playTime: this.audioRecorderPlayer.mmssss(
                //     Math.floor(e.currentPosition),
                // ),
                // duration: this.audioRecorderPlayer.mmssss(Math.floor(e.duration)),
            });

        });

    };

    onPausePlay = async () => {
        await this.audioRecorderPlayer.pausePlayer();
    };

    renderElement = (id, audioLength) => {
        if (this.state.selectedOptionId == id) {
            // this.onStartPlay(url)
            return (

                <Fcon name={this.state.selectedOptionId == id ? 'play' : 'pasue'} size={24} color={'white'} />
            )
        }
        if (this.state.selectedOptionId !== id || this.state.currentPositionSec == this.state.duration) {
            // this.onPausePlay(url)
            return (
                <Fcon name={'play'} size={24} color={'white'} />

            )
        }

    }



    checkFunction = async (id, url) => {
        console.log("id: before", id)
        await this.setState({
            selectedOptionId: id,
            setId: id
        })
        console.log('id:after', this.state.selectedOptionId)
        id == this.state.setId ? this.onStartPlay(id, url) : this.onPausePlay()
        // return this.state.selectedOptionId

    }


    render() {

        let { id, user, url, heights, message, audioLength, type } = this.props;

        let playWidthMessage =
            (this.state.currentPositionSec / this.state.currentDurationSec) *
            (screenWidth - 300);

        if (!playWidthMessage) {
            playWidthMessage = 0;
        }

        return (

            <View id={id}>
         
                {
                url.endsWith(".jpg") ?
                    < View key={id} style={[user == 1 ? styles.receiver : styles.sender, { paddingHorizontal: 14, paddingVertical: 8, borderRadius: heights > 50 ? 20 : 50 }]}>
                        <View style={{ alignItems: 'center', }}>
                            {console.log("address", url)}
                            <Image
                                resizeMode="contain"
                                // resizeMethod="scale"
                                style={{ width: 200, height: 200 }}
                                source={{ uri: url, width: 200, height: 200 }}

                            // source={{ uri: "https://picsum.photos/200", width: 200, height: 200 }}
                            // source={require("https://ibb.co/hM8BbY5")}
                            />
                        </View>

                    </View> : null

                }



                {
                    url.endsWith(".mp3") ?
                        (
                            <View key={this.props.id} style={[user == 1 ? styles.receiver : styles.sender, { paddingHorizontal: 14, paddingVertical: 8, borderRadius: heights > 50 ? 20 : 50 }]}>


                                <View style={[styles.viewPlayer, { backgroundColor: user == 1 ? darkgrey : '#0096FF', alignSelf: 'center', borderRadius: 50, flexDirection: 'row', justifyContent: "center", alignItems: 'center' }]}>

                                    {/* line */}
                                    <TouchableOpacity activeOpacity={0.5} onPress={() => {
                                        this.checkFunction(id, url)
                                    }} style={{ borderRadius: 50, width: 36, height: 36, justifyContent: 'center', alignItems: 'center' }}>

                                        <View>
                                            {this.renderElement(id, url, audioLength)}
                                        </View>

                                    </TouchableOpacity>
                                    <View >
                                        <TouchableOpacity
                                            style={[styles.viewBarWrapper, { width: screenWidth - 300 }]}
                                            onPress={this.onStatusPress}
                                        >
                                        
                                        
                                            {id == this.state.setId ?
                                                (<View style={[styles.viewBar, { flexDirection: 'row', }]}>
                                                    {/* {console.log("playWidth:", this.state.playWidth)} */}
                                                    <View style={[styles.viewBarPlay, { width: playWidthMessage }]} />
                                                </View>

                                                )
                                                : <View><Text>ddd</Text></View>}
                                        </TouchableOpacity>
                                    </View>
                                    <Text style={[styles.txtRecordCounter, { color: 'white' }]}>{audioLength}</Text>
                                </View>
                            </View >) : null
                }

                {
                    type == "txt" ?
                        // && user == 1 ?
                        <View key={id} >
                            <TouchableOpacity onPress={async () => await this.setState({ tempId: id })} style={[styles.receiver, { borderRadius: heights > 50 ? 20 : 50, backgroundColor: this.state.tempId == id ? 'pink' : 'yellow' }]}>
                                <Text style={styles.receiverText}>{message}</Text>
                            </TouchableOpacity>
                        </View> : null
                }
            </View >

        )
    }
}

Maintain the selected audio id in your parent component, pass it to child components using props, animate based on the condition. in ur message component

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