feat: update react-native-paper
This commit is contained in:
@@ -61,6 +61,13 @@ export default function TabLayout() {
|
||||
tabBarIcon: ({ color }) => <TabBarIcon name="rocket" color={color} />,
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="paper"
|
||||
options={{
|
||||
title: 'Paper UI',
|
||||
tabBarIcon: ({ color }) => <TabBarIcon name="paint-brush" color={color} />,
|
||||
}}
|
||||
/>
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
|
||||
309
app/(tabs)/paper.tsx
Normal file
309
app/(tabs)/paper.tsx
Normal file
@@ -0,0 +1,309 @@
|
||||
import React, { useState } from 'react';
|
||||
import { ScrollView, StyleSheet, View } from 'react-native';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Chip,
|
||||
FAB,
|
||||
IconButton,
|
||||
List,
|
||||
ProgressBar,
|
||||
Searchbar,
|
||||
SegmentedButtons,
|
||||
Snackbar,
|
||||
Switch,
|
||||
Text,
|
||||
TextInput,
|
||||
useTheme,
|
||||
} from 'react-native-paper';
|
||||
|
||||
export default function PaperDemo() {
|
||||
const theme = useTheme();
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [text, setText] = useState('');
|
||||
const [switchValue, setSwitchValue] = useState(false);
|
||||
const [snackbarVisible, setSnackbarVisible] = useState(false);
|
||||
const [segmentedValue, setSegmentedValue] = useState('walk');
|
||||
const [expanded, setExpanded] = useState(true);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ScrollView style={styles.scrollView} contentContainerStyle={styles.content}>
|
||||
{/* 标题 */}
|
||||
<Text variant="headlineLarge" style={styles.title}>
|
||||
React Native Paper
|
||||
</Text>
|
||||
<Text variant="bodyMedium" style={styles.subtitle}>
|
||||
Material Design 组件库示例
|
||||
</Text>
|
||||
|
||||
{/* 搜索框 */}
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Text variant="titleMedium" style={styles.sectionTitle}>
|
||||
🔍 搜索框
|
||||
</Text>
|
||||
<Searchbar
|
||||
placeholder="搜索..."
|
||||
onChangeText={setSearchQuery}
|
||||
value={searchQuery}
|
||||
style={styles.searchbar}
|
||||
/>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
{/* 输入框 */}
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Text variant="titleMedium" style={styles.sectionTitle}>
|
||||
✏️ 输入框
|
||||
</Text>
|
||||
<TextInput
|
||||
label="标准输入框"
|
||||
value={text}
|
||||
onChangeText={setText}
|
||||
mode="outlined"
|
||||
style={styles.input}
|
||||
/>
|
||||
<TextInput
|
||||
label="扁平输入框"
|
||||
value={text}
|
||||
onChangeText={setText}
|
||||
mode="flat"
|
||||
style={styles.input}
|
||||
/>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
{/* 按钮 */}
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Text variant="titleMedium" style={styles.sectionTitle}>
|
||||
🔘 按钮
|
||||
</Text>
|
||||
<View style={styles.buttonRow}>
|
||||
<Button mode="contained" onPress={() => setSnackbarVisible(true)}>
|
||||
Contained
|
||||
</Button>
|
||||
<Button mode="outlined" onPress={() => setSnackbarVisible(true)}>
|
||||
Outlined
|
||||
</Button>
|
||||
</View>
|
||||
<View style={styles.buttonRow}>
|
||||
<Button mode="text" onPress={() => setSnackbarVisible(true)}>
|
||||
Text
|
||||
</Button>
|
||||
<Button
|
||||
mode="elevated"
|
||||
onPress={() => setSnackbarVisible(true)}
|
||||
icon="camera"
|
||||
>
|
||||
With Icon
|
||||
</Button>
|
||||
</View>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
{/* 分段按钮 */}
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Text variant="titleMedium" style={styles.sectionTitle}>
|
||||
📊 分段按钮
|
||||
</Text>
|
||||
<SegmentedButtons
|
||||
value={segmentedValue}
|
||||
onValueChange={setSegmentedValue}
|
||||
buttons={[
|
||||
{
|
||||
value: 'walk',
|
||||
label: '步行',
|
||||
icon: 'walk',
|
||||
},
|
||||
{
|
||||
value: 'train',
|
||||
label: '火车',
|
||||
icon: 'train',
|
||||
},
|
||||
{ value: 'drive', label: '驾车', icon: 'car' },
|
||||
]}
|
||||
/>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
{/* 开关和芯片 */}
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Text variant="titleMedium" style={styles.sectionTitle}>
|
||||
🎛️ 开关和芯片
|
||||
</Text>
|
||||
<View style={styles.row}>
|
||||
<Text variant="bodyLarge">启用通知</Text>
|
||||
<Switch value={switchValue} onValueChange={setSwitchValue} />
|
||||
</View>
|
||||
<View style={styles.chipContainer}>
|
||||
<Chip icon="star" onPress={() => {}}>
|
||||
收藏
|
||||
</Chip>
|
||||
<Chip icon="heart" mode="outlined" onPress={() => {}}>
|
||||
喜欢
|
||||
</Chip>
|
||||
<Chip
|
||||
icon="close"
|
||||
onPress={() => {}}
|
||||
onClose={() => {}}
|
||||
closeIcon="close-circle"
|
||||
>
|
||||
可关闭
|
||||
</Chip>
|
||||
</View>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
{/* 进度条 */}
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Text variant="titleMedium" style={styles.sectionTitle}>
|
||||
📈 进度条
|
||||
</Text>
|
||||
<ProgressBar progress={0.7} style={styles.progressBar} />
|
||||
<ProgressBar progress={0.5} color={theme.colors.secondary} />
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
{/* 列表 */}
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Text variant="titleMedium" style={styles.sectionTitle}>
|
||||
📋 列表
|
||||
</Text>
|
||||
<List.Section>
|
||||
<List.Accordion
|
||||
title="可展开列表"
|
||||
left={(props) => <List.Icon {...props} icon="folder" />}
|
||||
expanded={expanded}
|
||||
onPress={() => setExpanded(!expanded)}
|
||||
>
|
||||
<List.Item title="第一项" left={(props) => <List.Icon {...props} icon="file" />} />
|
||||
<List.Item title="第二项" left={(props) => <List.Icon {...props} icon="file" />} />
|
||||
</List.Accordion>
|
||||
</List.Section>
|
||||
<List.Item
|
||||
title="带描述的列表项"
|
||||
description="这是一个描述文本"
|
||||
left={(props) => <List.Icon {...props} icon="account" />}
|
||||
right={(props) => <List.Icon {...props} icon="chevron-right" />}
|
||||
/>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
{/* 卡片示例 */}
|
||||
<Card style={styles.card}>
|
||||
<Card.Cover source={{ uri: 'https://picsum.photos/700' }} />
|
||||
<Card.Title
|
||||
title="卡片标题"
|
||||
subtitle="卡片副标题"
|
||||
left={(props) => <IconButton {...props} icon="image" />}
|
||||
right={(props) => <IconButton {...props} icon="dots-vertical" />}
|
||||
/>
|
||||
<Card.Content>
|
||||
<Text variant="bodyMedium">
|
||||
这是一个完整的卡片示例,包含封面图片、标题、内容和操作按钮。
|
||||
</Text>
|
||||
</Card.Content>
|
||||
<Card.Actions>
|
||||
<Button>取消</Button>
|
||||
<Button>确定</Button>
|
||||
</Card.Actions>
|
||||
</Card>
|
||||
|
||||
{/* 底部留白 */}
|
||||
<View style={styles.bottomSpace} />
|
||||
</ScrollView>
|
||||
|
||||
{/* 浮动操作按钮 */}
|
||||
<FAB
|
||||
icon="plus"
|
||||
style={styles.fab}
|
||||
onPress={() => setSnackbarVisible(true)}
|
||||
label="添加"
|
||||
/>
|
||||
|
||||
{/* 提示条 */}
|
||||
<Snackbar
|
||||
visible={snackbarVisible}
|
||||
onDismiss={() => setSnackbarVisible(false)}
|
||||
duration={3000}
|
||||
action={{
|
||||
label: '撤销',
|
||||
onPress: () => {
|
||||
// 撤销操作
|
||||
},
|
||||
}}
|
||||
>
|
||||
操作成功!
|
||||
</Snackbar>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
},
|
||||
content: {
|
||||
padding: 16,
|
||||
},
|
||||
title: {
|
||||
marginBottom: 8,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
subtitle: {
|
||||
marginBottom: 24,
|
||||
opacity: 0.7,
|
||||
},
|
||||
card: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
sectionTitle: {
|
||||
marginBottom: 12,
|
||||
fontWeight: '600',
|
||||
},
|
||||
searchbar: {
|
||||
marginTop: 8,
|
||||
},
|
||||
input: {
|
||||
marginBottom: 12,
|
||||
},
|
||||
buttonRow: {
|
||||
flexDirection: 'row',
|
||||
gap: 8,
|
||||
marginBottom: 8,
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: 16,
|
||||
},
|
||||
chipContainer: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
gap: 8,
|
||||
},
|
||||
progressBar: {
|
||||
marginBottom: 12,
|
||||
},
|
||||
bottomSpace: {
|
||||
height: 80,
|
||||
},
|
||||
fab: {
|
||||
position: 'absolute',
|
||||
margin: 16,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ import * as Updates from 'expo-updates';
|
||||
import { useEffect } from 'react';
|
||||
import { Alert, Platform } from 'react-native';
|
||||
import 'react-native-reanimated';
|
||||
import { PaperProvider, MD3DarkTheme, MD3LightTheme } from 'react-native-paper';
|
||||
|
||||
import { useColorScheme } from '@/components/useColorScheme';
|
||||
|
||||
@@ -90,13 +91,16 @@ export default function RootLayout() {
|
||||
|
||||
function RootLayoutNav() {
|
||||
const colorScheme = useColorScheme();
|
||||
const paperTheme = colorScheme === 'dark' ? MD3DarkTheme : MD3LightTheme;
|
||||
|
||||
return (
|
||||
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
||||
<Stack>
|
||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
|
||||
</Stack>
|
||||
</ThemeProvider>
|
||||
<PaperProvider theme={paperTheme}>
|
||||
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
||||
<Stack>
|
||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
|
||||
</Stack>
|
||||
</ThemeProvider>
|
||||
</PaperProvider>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user