|
|
import { StyleSheet, ScrollView, TouchableOpacity, View, Text, useColorScheme as useSystemColorScheme } from 'react-native'; |
|
|
import { Stack } from 'expo-router'; |
|
|
import { useState, useEffect, useMemo } from 'react'; |
|
|
import { useTheme, useSettingsActions } from '@/stores'; |
|
|
import { useHaptics } from '@/hooks'; |
|
|
import Colors from '@/constants/Colors'; |
|
|
|
|
|
export default function ThemeTestScreen() { |
|
|
const currentTheme = useTheme(); |
|
|
const { setTheme } = useSettingsActions(); |
|
|
const haptics = useHaptics(); |
|
|
const systemColorScheme = useSystemColorScheme(); |
|
|
|
|
|
// 强制重新渲染的状态 |
|
|
const [renderKey, setRenderKey] = useState(0); |
|
|
|
|
|
// 直接计算实际应用的主题 - 不使用 useColorScheme hook |
|
|
const actualTheme: 'light' | 'dark' = useMemo(() => { |
|
|
return currentTheme === 'auto' |
|
|
? (systemColorScheme === 'dark' ? 'dark' : 'light') |
|
|
: currentTheme; |
|
|
}, [currentTheme, systemColorScheme]); |
|
|
|
|
|
// 使用 useMemo 确保颜色对象在主题改变时重新计算 |
|
|
const colors = useMemo(() => { |
|
|
console.log('🎨 Recalculating colors for theme:', actualTheme); |
|
|
return Colors[actualTheme] as Record<string, any>; |
|
|
}, [actualTheme]); |
|
|
|
|
|
// 监听主题变化 |
|
|
useEffect(() => { |
|
|
console.log('🎨 Theme changed:', { currentTheme, systemColorScheme, actualTheme, renderKey }); |
|
|
setRenderKey(prev => prev + 1); |
|
|
}, [currentTheme, systemColorScheme, actualTheme]); |
|
|
|
|
|
const handleThemeChange = (newTheme: 'light' | 'dark' | 'auto') => { |
|
|
haptics.selection(); |
|
|
console.log('🎨 Changing theme to:', newTheme); |
|
|
setTheme(newTheme); |
|
|
}; |
|
|
|
|
|
return ( |
|
|
<> |
|
|
<Stack.Screen |
|
|
options={{ |
|
|
title: '主题测试', |
|
|
headerStyle: { |
|
|
backgroundColor: colors.background, |
|
|
}, |
|
|
headerTintColor: colors.text, |
|
|
}} |
|
|
/> |
|
|
<ScrollView |
|
|
style={[styles.container, { backgroundColor: colors.background }]} |
|
|
> |
|
|
{/* 主题信息 */} |
|
|
<View style={[styles.section, { backgroundColor: colors.backgroundSecondary }]}> |
|
|
<Text style={[styles.title, { color: colors.text }]}> |
|
|
当前主题信息 |
|
|
</Text> |
|
|
<Text style={[styles.infoText, { color: colors.textSecondary }]}> |
|
|
用户设置: {currentTheme} |
|
|
</Text> |
|
|
<Text style={[styles.infoText, { color: colors.textSecondary }]}> |
|
|
系统主题: {systemColorScheme || 'light'} |
|
|
</Text> |
|
|
<Text style={[styles.infoText, { color: colors.textSecondary }]}> |
|
|
实际应用: {actualTheme} |
|
|
</Text> |
|
|
<Text style={[styles.infoText, { color: colors.textSecondary }]}> |
|
|
渲染次数: {renderKey} |
|
|
</Text> |
|
|
</View> |
|
|
|
|
|
{/* 主题切换按钮 */} |
|
|
<View style={[styles.section, { backgroundColor: colors.backgroundSecondary }]}> |
|
|
<Text style={[styles.title, { color: colors.text }]}> |
|
|
切换主题 |
|
|
</Text> |
|
|
<View style={styles.buttonRow}> |
|
|
<TouchableOpacity |
|
|
style={[ |
|
|
styles.themeButton, |
|
|
{ |
|
|
backgroundColor: currentTheme === 'light' ? colors.primary : colors.backgroundTertiary, |
|
|
borderColor: colors.border, |
|
|
} |
|
|
]} |
|
|
onPress={() => handleThemeChange('light')} |
|
|
> |
|
|
<Text style={[ |
|
|
styles.buttonText, |
|
|
{ color: currentTheme === 'light' ? '#fff' : colors.text } |
|
|
]}> |
|
|
☀️ 浅色 |
|
|
</Text> |
|
|
</TouchableOpacity> |
|
|
|
|
|
<TouchableOpacity |
|
|
style={[ |
|
|
styles.themeButton, |
|
|
{ |
|
|
backgroundColor: currentTheme === 'dark' ? colors.primary : colors.backgroundTertiary, |
|
|
borderColor: colors.border, |
|
|
} |
|
|
]} |
|
|
onPress={() => handleThemeChange('dark')} |
|
|
> |
|
|
<Text style={[ |
|
|
styles.buttonText, |
|
|
{ color: currentTheme === 'dark' ? '#fff' : colors.text } |
|
|
]}> |
|
|
🌙 深色 |
|
|
</Text> |
|
|
</TouchableOpacity> |
|
|
|
|
|
<TouchableOpacity |
|
|
style={[ |
|
|
styles.themeButton, |
|
|
{ |
|
|
backgroundColor: currentTheme === 'auto' ? colors.primary : colors.backgroundTertiary, |
|
|
borderColor: colors.border, |
|
|
} |
|
|
]} |
|
|
onPress={() => handleThemeChange('auto')} |
|
|
> |
|
|
<Text style={[ |
|
|
styles.buttonText, |
|
|
{ color: currentTheme === 'auto' ? '#fff' : colors.text } |
|
|
]}> |
|
|
🔄 自动 |
|
|
</Text> |
|
|
</TouchableOpacity> |
|
|
</View> |
|
|
</View> |
|
|
|
|
|
{/* 文本颜色展示 */} |
|
|
<View style={[styles.section, { backgroundColor: colors.backgroundSecondary }]}> |
|
|
<Text style={[styles.title, { color: colors.text }]}> |
|
|
文本颜色 |
|
|
</Text> |
|
|
<Text style={[styles.colorText, { color: colors.text }]}> |
|
|
Primary Text - {colors.text} |
|
|
</Text> |
|
|
<Text style={[styles.colorText, { color: colors.textSecondary }]}> |
|
|
Secondary Text - {colors.textSecondary} |
|
|
</Text> |
|
|
<Text style={[styles.colorText, { color: colors.textTertiary }]}> |
|
|
Tertiary Text - {colors.textTertiary} |
|
|
</Text> |
|
|
</View> |
|
|
|
|
|
{/* 背景颜色展示 */} |
|
|
<View style={[styles.section, { backgroundColor: colors.backgroundSecondary }]}> |
|
|
<Text style={[styles.title, { color: colors.text }]}> |
|
|
背景颜色 |
|
|
</Text> |
|
|
<View style={[styles.colorBox, { backgroundColor: colors.background }]}> |
|
|
<Text style={[styles.colorText, { color: colors.text }]}> |
|
|
Primary Background - {colors.background} |
|
|
</Text> |
|
|
</View> |
|
|
<View style={[styles.colorBox, { backgroundColor: colors.backgroundSecondary, borderWidth: 1, borderColor: colors.border }]}> |
|
|
<Text style={[styles.colorText, { color: colors.text }]}> |
|
|
Secondary Background - {colors.backgroundSecondary} |
|
|
</Text> |
|
|
</View> |
|
|
<View style={[styles.colorBox, { backgroundColor: colors.backgroundTertiary }]}> |
|
|
<Text style={[styles.colorText, { color: colors.text }]}> |
|
|
Tertiary Background - {colors.backgroundTertiary} |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
|
|
|
{/* 主题颜色展示 */} |
|
|
<View style={[styles.section, { backgroundColor: colors.backgroundSecondary }]}> |
|
|
<Text style={[styles.title, { color: colors.text }]}> |
|
|
主题颜色 |
|
|
</Text> |
|
|
<View style={styles.colorGrid}> |
|
|
<View style={[styles.colorBox, { backgroundColor: colors.primary }]}> |
|
|
<Text style={[styles.colorText, { color: '#fff' }]}>Primary - {colors.primary}</Text> |
|
|
</View> |
|
|
<View style={[styles.colorBox, { backgroundColor: colors.secondary }]}> |
|
|
<Text style={[styles.colorText, { color: '#fff' }]}>Secondary - {colors.secondary}</Text> |
|
|
</View> |
|
|
<View style={[styles.colorBox, { backgroundColor: colors.success }]}> |
|
|
<Text style={[styles.colorText, { color: '#fff' }]}>Success - {colors.success}</Text> |
|
|
</View> |
|
|
<View style={[styles.colorBox, { backgroundColor: colors.warning }]}> |
|
|
<Text style={[styles.colorText, { color: '#fff' }]}>Warning - {colors.warning}</Text> |
|
|
</View> |
|
|
<View style={[styles.colorBox, { backgroundColor: colors.error }]}> |
|
|
<Text style={[styles.colorText, { color: '#fff' }]}>Error - {colors.error}</Text> |
|
|
</View> |
|
|
<View style={[styles.colorBox, { backgroundColor: colors.info }]}> |
|
|
<Text style={[styles.colorText, { color: '#fff' }]}>Info - {colors.info}</Text> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
|
|
|
{/* UI 元素展示 */} |
|
|
<View style={[styles.section, { backgroundColor: colors.backgroundSecondary }]}> |
|
|
<Text style={[styles.title, { color: colors.text }]}> |
|
|
UI 元素 |
|
|
</Text> |
|
|
<View style={[styles.card, { backgroundColor: colors.card, borderColor: colors.border }]}> |
|
|
<Text style={[styles.cardText, { color: colors.text }]}> |
|
|
这是一个卡片组件 |
|
|
</Text> |
|
|
<Text style={[styles.cardSubtext, { color: colors.textSecondary }]}> |
|
|
卡片背景色: {colors.card} |
|
|
</Text> |
|
|
</View> |
|
|
|
|
|
<View style={[styles.input, { backgroundColor: colors.inputBackground, borderColor: colors.inputBorder }]}> |
|
|
<Text style={[styles.inputText, { color: colors.textSecondary }]}> |
|
|
输入框样式预览 |
|
|
</Text> |
|
|
</View> |
|
|
|
|
|
<View style={[styles.separator, { backgroundColor: colors.separator }]} /> |
|
|
|
|
|
<TouchableOpacity style={[styles.button, { backgroundColor: colors.buttonPrimary }]}> |
|
|
<Text style={[styles.buttonText, { color: '#fff' }]}> |
|
|
按钮示例 |
|
|
</Text> |
|
|
</TouchableOpacity> |
|
|
</View> |
|
|
</ScrollView> |
|
|
</> |
|
|
); |
|
|
} |
|
|
|
|
|
const styles = StyleSheet.create({ |
|
|
container: { |
|
|
flex: 1, |
|
|
}, |
|
|
section: { |
|
|
margin: 16, |
|
|
padding: 16, |
|
|
borderRadius: 12, |
|
|
}, |
|
|
title: { |
|
|
fontSize: 20, |
|
|
fontWeight: 'bold', |
|
|
marginBottom: 16, |
|
|
}, |
|
|
infoText: { |
|
|
fontSize: 16, |
|
|
marginBottom: 8, |
|
|
}, |
|
|
buttonRow: { |
|
|
flexDirection: 'row', |
|
|
gap: 12, |
|
|
}, |
|
|
themeButton: { |
|
|
flex: 1, |
|
|
paddingVertical: 12, |
|
|
paddingHorizontal: 16, |
|
|
borderRadius: 8, |
|
|
borderWidth: 2, |
|
|
alignItems: 'center', |
|
|
}, |
|
|
buttonText: { |
|
|
fontSize: 16, |
|
|
fontWeight: '600', |
|
|
}, |
|
|
colorText: { |
|
|
fontSize: 14, |
|
|
marginBottom: 8, |
|
|
fontFamily: 'monospace', |
|
|
}, |
|
|
colorBox: { |
|
|
padding: 16, |
|
|
borderRadius: 8, |
|
|
marginBottom: 8, |
|
|
alignItems: 'center', |
|
|
}, |
|
|
colorGrid: { |
|
|
gap: 8, |
|
|
}, |
|
|
card: { |
|
|
padding: 16, |
|
|
borderRadius: 8, |
|
|
borderWidth: 1, |
|
|
marginBottom: 12, |
|
|
}, |
|
|
cardText: { |
|
|
fontSize: 16, |
|
|
fontWeight: '600', |
|
|
marginBottom: 4, |
|
|
}, |
|
|
cardSubtext: { |
|
|
fontSize: 12, |
|
|
fontFamily: 'monospace', |
|
|
}, |
|
|
input: { |
|
|
padding: 12, |
|
|
borderRadius: 8, |
|
|
borderWidth: 1, |
|
|
marginBottom: 12, |
|
|
}, |
|
|
inputText: { |
|
|
fontSize: 14, |
|
|
}, |
|
|
separator: { |
|
|
height: 1, |
|
|
marginVertical: 12, |
|
|
}, |
|
|
button: { |
|
|
padding: 16, |
|
|
borderRadius: 8, |
|
|
alignItems: 'center', |
|
|
}, |
|
|
}); |
|
|
|
|
|
|