我正在尝试构建一个使用 Expo AV 播放音频文件的组件。在音频可用之前,我希望组件以降低的不透明度(不透明度 = 0.2)进行渲染。音频加载后,我希望按钮完全不透明。我尝试使用 useEffect 钩子(没有依赖项,只想在组件安装时加载一次音频文件)和一个名为“isLoaded”的状态变量来实现这一点。代码如下:
const AudioPlayer = ({ containerStyle }) => {
const [isPlaying, setIsPlaying] = useState(false);
const [voice, setVoice] = useState(undefined);
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
const fetchSound = async () => {
const { sound } = await Audio.Sound.createAsync(DEFAULT_AUDIO_PATH);
setVoice(sound);
setIsLoaded(true);
}
fetchSound();
}, []);
const playSound = async () => {
if (isLoaded) {
try {
voice.setOnPlaybackStatusUpdate(status => {
status.didJustFinish ? setIsPlaying(false) : null;
});
setIsPlaying(true);
await voice.replayAsync();
} catch (e) {
console.log(e);
}
}
}
return (
<TouchableOpacity
style={isLoaded ? [styles.container, containerStyle] : [styles.unloaded, containerStyle]}
onPress={playSound}>
<View style={styles.icon_wrapper}>
<FontAwesome
name={isPlaying ? 'volume-up' : 'play'}
style={styles.icon}
/>
</View>
</TouchableOpacity>
);
}
组件不透明度在我按下按钮之前不会改变,此时组件开始按预期呈现,因此很明显 isLoaded 状态是从 useEffect 钩子设置的。我在这里做错了什么?
答案 0 :(得分:0)
对于任何有类似问题的人 - TouchableOpacity 似乎存在一个错误,即对元素所做的任何不透明度更改仅在按下组件时触发。
要解决此问题,只需将 TouchableOpacity 更改为 Pressable。