我正在构建一个秒表,其中有一个计时器,计时器应该运行保存时间到存储器,以便能够检索它,并从计时器到达的地方恢复应用程序被杀死,然后重新启动。所以问题是,时间被保存,但当我试图检索它,该值为0,而不是保存的值.我需要你的帮助,请能够检索正确的值,如果我保存它的权利.这种保存的方式,我从建立一个以前的应用程序是完美的工作,但我现在正在开发的应用程序中没有
我正在我的物理真实的手机上测试Expo Go应用程序
下面是我的代码:
import React, { useState, useRef, useEffect, useCallback } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, Image, Modal, Platform } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
export default function StopwatchScreen() {
const [menuVisible, setMenuVisible] = useState(false);
const [backgroundColor, setBackgroundColor] = useState('#11167F');
const [headerBackgroundColor, setHeaderBackgroundColor] = useState('#0a1055');
const [isRunning, setIsRunning] = useState(false);
const [time, setTime] = useState(0);
const [retrievedTime, setRetrievedTime] = useState(0);
const intervalRef = useRef(null);
const handleLapButtonPress = useCallback(() => {
if(isRunning) {
} else {
setTime(0);
setRetrievedTime(0);
saveAsync('time', 0);
console.log("cleared time: ", time);
console.log("cleared retrieved time: ", retrievedTime);
}
}, [isRunning]);
const handleStartButtonPress = async () => {
setIsRunning(!isRunning);
saveAsync('isRunning', !isRunning);
saveAsync('time', time);
};
useEffect(() => {
if (isRunning) {
console.log("it is running");
intervalRef.current = setInterval(() => {
if(retrievedTime > 0) {
console.log("retrieved > 0");
setTime(previousTime => retrievedTime + previousTime + 100);
} else {
console.log("retrieved not > 0");
setTime(previousTime => previousTime + 100);
}
}, 100);
} else {
clearInterval(intervalRef.current);
console.log("it stopped");
}
return () => clearInterval(intervalRef.current);
}, [isRunning]);
useEffect(() => {
saveAsync('time', time);
}, [time]);
const toggleMenu = () => {
setMenuVisible(!menuVisible);
}
const displayTime = () => {
const milliseconds = parseInt((time%1000)/10);
const centiseconds = Math.floor(milliseconds/10);
const seconds = parseInt((time/1000)%60);
const minutes = parseInt((time/(1000*60))%60)
const hours = parseInt((time/(1000*60*60))%24);
return {
hours: pad(hours),
minutesSeconds: pad(minutes % 60) + ':' + pad(seconds % 60),
centiseconds: centiseconds,
};
};
const pad = (number) => {
return number < 10 ? '0' + number : number;
};
const retrieveAsync = async (key) => {
try {
const jsonValue = await AsyncStorage.getItem(key);
if (jsonValue !== null) {
const parsedValue = JSON.parse(jsonValue);
console.log("parsedValue: ", parsedValue);
if(key === 'time') {
setRetrievedTime(parsedValue);
console.log("retrieve "+key+" inside: ", retrievedTime);
}
}
} catch (e) {
// error reading value
console.log('error: ', e);
}
};
const saveAsync = async (key, value) => {
AsyncStorage.setItem(key, JSON.stringify(value));
console.log(key+" value saved: ", value);
};
useEffect(() => {
console.log("Real retrieved time: ", retrievedTime);
setTime(previousTime => previousTime + retrievedTime);
}, [retrievedTime]);
useEffect(() => {
retrieveAsync('time');
console.log("useEffect retrieved time: ", retrievedTime);
}, []);
return (
<View style={[styles.container, Platform.OS === 'android' && styles.androidPadding]}>
<View style={[styles.header, {backgroundColor: headerBackgroundColor}]}>
<Text style={[styles.title, styles.textFont]}>Futuristic Stopwatch</Text>
<TouchableOpacity onPress={toggleMenu}>
<Image source={require('../assets/images/three_dots.png')} style={styles.dotsIcon} />
</TouchableOpacity>
</View>
<Modal
transparent={false}
animationType="slide"
visible={menuVisible}
onRequestClose={() => setMenuVisible(false)}
>
<View style={styles.modalContainer}>
Modal
</View>
</Modal>
<View style={[styles.contentContainer, {backgroundColor: backgroundColor}]}>
<View style={styles.rowHud}>
<Text style={[styles.hoursTimerOverlay, styles.textFont]}>{`${displayTime(time).hours}`}</Text>
<Text style={[styles.timerOverlay, styles.textFont]}>{`${displayTime(time).minutesSeconds}`}</Text>
<Text style={[styles.centisecondsTimerOverlay, styles.textFont]}>{`${displayTime(time).centiseconds}`}</Text>
</View>
<View style={styles.controls}>
<TouchableOpacity onPress={handleStartButtonPress} style={[styles.controlButtonBorder, { backgroundColor: isRunning ? "#340e0d" : "#0a2a12" }]}>
<View style={styles.controlButton}>
<Text style={{ color: isRunning ? "#ea4c49" : "#37d05c" }}>{isRunning ? 'Stop' : 'Start'}</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={handleLapButtonPress} style={[styles.controlButtonBorder, { backgroundColor: isRunning ? "#333333" : "#1c1c1e" }]}>
<View style={styles.controlButton}>
<Text style={{ color: isRunning ? "#fff" : "#9d9ca2" }}>{isRunning ? 'Lap' : 'Reset'}</Text>
</View>
</TouchableOpacity>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
padding: 0,
},
androidPadding: {
paddingTop: Platform.OS === 'android' ? 25 : 0,
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 0,
paddingTop: 18,
paddingBottom: 15,
paddingLeft: 10,
paddingRight: 10,
},
title: {
fontSize: 18,
//fontWeight: 'bold',
color: 'white',
},
dotsIcon: {
width: 20,
height: 20,
resizeMode: 'contain',
},
modalContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
textFont: {
fontFamily: 'Orbitron Black',
},
modalContent: {
backgroundColor: '#fff',
padding: 20,
borderRadius: 10,
elevation: 5,
},
closeButton: {
position: 'absolute',
top: 10,
right: 10,
},
sectionTitle: {
flexDirection: 'row',
alignItems: 'center',
marginTop: 10,
},
sectionTitleText: {
fontFamily: 'Orbitron Black',
},
radioBox: {
marginTop: 20,
alignItems: 'flex-start',
width: 300,
},
radioOptions: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
contentContainer: {
flex: 1,
},
rowHud: {
flex: 0.6,
flexDirection: 'row',
marginBottom: 0,
marginTop: 10
},
timerOverlay: {
position: 'absolute',
top: '50%', // Adjust as needed
left: '50%', // Adjust as needed
transform: [{ translateX: -90 }, { translateY: -30 }],
fontSize: 50,
color: 'white',
},
hoursTimerOverlay: {
position: 'absolute',
top: '35%', // Adjust as needed
left: '50%', // Adjust as needed
transform: [{ translateX: -30 }, { translateY: -30 }],
fontSize: 35,
color: 'white',
},
centisecondsTimerOverlay: {
position: 'absolute',
top: '71%', // Adjust as needed
left: '50%', // Adjust as needed
transform: [{ translateX: -15 }, { translateY: -35 }],
fontSize: 35,
color: 'white',
},
controls: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingLeft: 20,
paddingRight: 20,
},
controlButtonBorder: {
justifyContent: "center",
alignItems: "center",
width: 70,
height: 70,
borderRadius: 70,
},
controlButton: {
justifyContent: "center",
alignItems: "center",
width: 65,
height: 65,
borderRadius: 65,
borderColor: "#000",
borderWidth: 1
},
image: {
width: '100%',
height: '100%',
paddingLeft: 10,
paddingRight: 10
}
});
字符串
2条答案
按热度按时间uxh89sit1#
从AsyncStorage检索时间时,使用该值设置时间状态。
调整秒表运行时时间的添加方式。将上一时间和检索到的时间相加可能会导致不准确。
字符串
yhxst69z2#
请修改如下:
字符串
请让我知道这是否有帮助