【问题标题】:React-native FlatList rendering issueReact-native FlatList 渲染问题
【发布时间】:2021-10-01 11:48:05
【问题描述】:

问题

see the screenshot of probleme //下面的代码是加载滑块的..您还可以在 ClassFlatListRender.js 中找到下面的 sn-p ,当元素的 id 通过等于所选 Id 的 FlatList 传递时,音频滑块应该可以工作,但是如果我触发一个音频文件元素所有滑块都在移动

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

代码

我的代码结构是这样的:我有一个包含所有逻辑和状态的容器组件, 其中包含一个 FlatList 组件,该组件又包含一个自定义展示列表。

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

容器包含这个组件

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

自定义列表:

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>

        )
    }
} 

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 >

        )
    }
}

【问题讨论】:

    标签: reactjs react-native react-native-flatlist flatlist


    【解决方案1】:

    在父组件中维护选定的音频 id,使用道具将其传递给子组件,根据条件进行动画处理。在你的消息组件中

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-14
      • 2019-04-06
      • 1970-01-01
      • 2018-07-01
      • 1970-01-01
      • 2018-12-27
      • 2020-10-23
      相关资源
      最近更新 更多