Files
rn-app/app/theme-example.tsx
2025-11-06 16:37:01 +08:00

260 lines
7.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 主题系统使用示例
*
* 展示四种不同的主题样式使用方式
*/
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>
</>
);
}