|
|
/** |
|
|
* 主题系统使用示例 |
|
|
* |
|
|
* 展示四种不同的主题样式使用方式 |
|
|
*/ |
|
|
|
|
|
import { ScrollView, View, Text, TouchableOpacity } from 'react-native'; |
|
|
import { Stack } from 'expo-router'; |
|
|
import { |
|
|
useColorScheme, |
|
|
useThemeColors, |
|
|
useThemeInfo, |
|
|
commonStyles, |
|
|
createThemeStyles, |
|
|
ThemedText, |
|
|
ThemedView, |
|
|
} from '@/theme'; |
|
|
|
|
|
// 方式 3: 创建自定义主题样式(推荐用于复杂组件) |
|
|
const customStyles = createThemeStyles((colors) => ({ |
|
|
header: { |
|
|
backgroundColor: colors.primary, |
|
|
padding: 20, |
|
|
borderRadius: 12, |
|
|
marginBottom: 16, |
|
|
}, |
|
|
headerText: { |
|
|
color: '#FFFFFF', |
|
|
fontSize: 24, |
|
|
fontWeight: 'bold', |
|
|
textAlign: 'center', |
|
|
}, |
|
|
section: { |
|
|
backgroundColor: colors.card, |
|
|
padding: 16, |
|
|
borderRadius: 8, |
|
|
marginBottom: 16, |
|
|
borderWidth: 1, |
|
|
borderColor: colors.border, |
|
|
}, |
|
|
sectionTitle: { |
|
|
color: colors.text, |
|
|
fontSize: 18, |
|
|
fontWeight: '600', |
|
|
marginBottom: 12, |
|
|
}, |
|
|
codeBlock: { |
|
|
backgroundColor: colors.backgroundTertiary, |
|
|
padding: 12, |
|
|
borderRadius: 6, |
|
|
marginTop: 8, |
|
|
}, |
|
|
codeText: { |
|
|
color: colors.textSecondary, |
|
|
fontSize: 12, |
|
|
fontFamily: 'monospace', |
|
|
}, |
|
|
})); |
|
|
|
|
|
export default function ThemeExampleScreen() { |
|
|
const theme = useColorScheme(); |
|
|
const colors = useThemeColors(); |
|
|
const { isDark } = useThemeInfo(); |
|
|
const s = commonStyles[theme]; // 通用样式类 |
|
|
const custom = customStyles[theme]; // 自定义样式 |
|
|
|
|
|
return ( |
|
|
<> |
|
|
<Stack.Screen |
|
|
options={{ |
|
|
title: '主题系统示例', |
|
|
headerStyle: { |
|
|
backgroundColor: colors.background, |
|
|
}, |
|
|
headerTintColor: colors.text, |
|
|
}} |
|
|
/> |
|
|
<ScrollView style={s.containerPadded}> |
|
|
{/* 自定义样式示例 */} |
|
|
<View style={custom.header}> |
|
|
<Text style={custom.headerText}> |
|
|
主题系统使用示例 |
|
|
</Text> |
|
|
<Text style={[custom.headerText, { fontSize: 14, marginTop: 8 }]}> |
|
|
当前主题: {theme} {isDark ? '🌙' : '☀️'} |
|
|
</Text> |
|
|
</View> |
|
|
|
|
|
{/* 方式 1: 使用主题组件 */} |
|
|
<View style={custom.section}> |
|
|
<Text style={custom.sectionTitle}> |
|
|
方式 1: 使用主题组件 |
|
|
</Text> |
|
|
<ThemedView style={{ padding: 12, borderRadius: 6 }}> |
|
|
<ThemedText type="title">这是标题</ThemedText> |
|
|
<ThemedText type="subtitle">这是副标题</ThemedText> |
|
|
<ThemedText>这是普通文本</ThemedText> |
|
|
</ThemedView> |
|
|
<View style={custom.codeBlock}> |
|
|
<Text style={custom.codeText}> |
|
|
{`import { ThemedText, ThemedView } from '@/theme'; |
|
|
|
|
|
<ThemedView> |
|
|
<ThemedText type="title">标题</ThemedText> |
|
|
</ThemedView>`} |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
|
|
|
{/* 方式 2: 使用通用样式类 */} |
|
|
<View style={custom.section}> |
|
|
<Text style={custom.sectionTitle}> |
|
|
方式 2: 使用通用样式类(类似 CSS 类名) |
|
|
</Text> |
|
|
<View style={s.card}> |
|
|
<Text style={s.textTitle}>卡片标题</Text> |
|
|
<Text style={s.textSecondary}>卡片描述文本</Text> |
|
|
<View style={s.spacingMd} /> |
|
|
<TouchableOpacity style={s.button}> |
|
|
<Text style={s.buttonText}>主要按钮</Text> |
|
|
</TouchableOpacity> |
|
|
<View style={s.spacingSm} /> |
|
|
<TouchableOpacity style={s.buttonOutline}> |
|
|
<Text style={s.buttonTextOutline}>次要按钮</Text> |
|
|
</TouchableOpacity> |
|
|
</View> |
|
|
<View style={custom.codeBlock}> |
|
|
<Text style={custom.codeText}> |
|
|
{`import { useColorScheme, commonStyles } from '@/theme'; |
|
|
|
|
|
const theme = useColorScheme(); |
|
|
const s = commonStyles[theme]; |
|
|
|
|
|
<View style={s.card}> |
|
|
<Text style={s.textTitle}>标题</Text> |
|
|
<TouchableOpacity style={s.button}> |
|
|
<Text style={s.buttonText}>按钮</Text> |
|
|
</TouchableOpacity> |
|
|
</View>`} |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
|
|
|
{/* 方式 3: 使用自定义主题样式 */} |
|
|
<View style={custom.section}> |
|
|
<Text style={custom.sectionTitle}> |
|
|
方式 3: 使用自定义主题样式(推荐) |
|
|
</Text> |
|
|
<View style={{ padding: 12 }}> |
|
|
<Text style={{ color: colors.text }}> |
|
|
本页面的 header 和 section 就是使用自定义主题样式创建的 |
|
|
</Text> |
|
|
</View> |
|
|
<View style={custom.codeBlock}> |
|
|
<Text style={custom.codeText}> |
|
|
{`import { createThemeStyles } from '@/theme'; |
|
|
|
|
|
const styles = createThemeStyles((colors) => ({ |
|
|
header: { |
|
|
backgroundColor: colors.primary, |
|
|
padding: 20, |
|
|
}, |
|
|
headerText: { |
|
|
color: '#FFFFFF', |
|
|
fontSize: 24, |
|
|
}, |
|
|
})); |
|
|
|
|
|
const theme = useColorScheme(); |
|
|
<View style={styles[theme].header}> |
|
|
<Text style={styles[theme].headerText}>标题</Text> |
|
|
</View>`} |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
|
|
|
{/* 方式 4: 使用 Hooks + 内联样式 */} |
|
|
<View style={custom.section}> |
|
|
<Text style={custom.sectionTitle}> |
|
|
方式 4: 使用 Hooks + 内联样式(动态场景) |
|
|
</Text> |
|
|
<View style={{ |
|
|
backgroundColor: colors.backgroundSecondary, |
|
|
padding: 16, |
|
|
borderRadius: 8, |
|
|
}}> |
|
|
<Text style={{ color: colors.text, fontSize: 16 }}> |
|
|
这是使用 useThemeColors() 动态获取颜色的文本 |
|
|
</Text> |
|
|
<View style={{ height: 12 }} /> |
|
|
<Text style={{ color: colors.textSecondary, fontSize: 14 }}> |
|
|
适合需要动态计算样式的场景 |
|
|
</Text> |
|
|
</View> |
|
|
<View style={custom.codeBlock}> |
|
|
<Text style={custom.codeText}> |
|
|
{`import { useThemeColors } from '@/theme'; |
|
|
|
|
|
const colors = useThemeColors(); |
|
|
|
|
|
<View style={{ |
|
|
backgroundColor: colors.background, |
|
|
padding: 16, |
|
|
}}> |
|
|
<Text style={{ color: colors.text }}> |
|
|
动态文本 |
|
|
</Text> |
|
|
</View>`} |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
|
|
|
{/* 颜色展示 */} |
|
|
<View style={custom.section}> |
|
|
<Text style={custom.sectionTitle}> |
|
|
主题颜色展示 |
|
|
</Text> |
|
|
<View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 8 }}> |
|
|
{Object.entries(colors).map(([key, value]) => ( |
|
|
<View |
|
|
key={key} |
|
|
style={{ |
|
|
backgroundColor: value as string, |
|
|
padding: 8, |
|
|
borderRadius: 6, |
|
|
minWidth: 100, |
|
|
borderWidth: 1, |
|
|
borderColor: colors.border, |
|
|
}} |
|
|
> |
|
|
<Text style={{ |
|
|
color: key.includes('background') || key.includes('card') || key.includes('input') |
|
|
? colors.text |
|
|
: '#FFFFFF', |
|
|
fontSize: 10, |
|
|
fontWeight: '600', |
|
|
}}> |
|
|
{key} |
|
|
</Text> |
|
|
<Text style={{ |
|
|
color: key.includes('background') || key.includes('card') || key.includes('input') |
|
|
? colors.textSecondary |
|
|
: '#FFFFFF', |
|
|
fontSize: 8, |
|
|
}}> |
|
|
{value} |
|
|
</Text> |
|
|
</View> |
|
|
))} |
|
|
</View> |
|
|
</View> |
|
|
|
|
|
{/* 底部间距 */} |
|
|
<View style={s.spacingXl} /> |
|
|
</ScrollView> |
|
|
</> |
|
|
); |
|
|
} |
|
|
|
|
|
|